通知状态栏(status bar notification)是一个包含图片和通知信息加上可选的ticker-text信息,当用户选择的时候,android系统会开启一个意图intent(通常是启动一个activity).你当然可以设置以铃声,震动,灯光等来通知用户。
状态通知栏应该发生在当后台服务程序想提醒需要用户相应的事件,android建议开发这,后台服务程序不应该在需要与用户交互的时候直接启动一个活动界面,你的后台程序应该创建一个状态通知,用户可以选择这个通知来启动某个活动界面。activity和service都可以生成通知,但是你会通常在service里实例化它。这个时候你需要用到两个类:Notification and NotificationManager。
Notification定义的是通知的属性,而NotificationManager是android系统执行和管理状态栏中所有的通知。NotificationManager只能通过getSystemService()实例化,通过notify()来传递某个Notification实例。
创建你的Notification:
创建一个Notification需要一张出现在状态栏里图片,标题于信息(除非你自定义status bar),一个意图(用户选择时候出发)。还有几个是可选的:ticker-text(至于这个提示信息,就是通知刚出现的时候跟图表一起出现的信息,稍后就会和通知的图标自动消失),声音,震动设置,灯光。基本的实例化一个notification代码如下:
1 int icon = R.drawable.notification_icon; // icon from resources
2 CharSequence tickerText = "Hello"; // ticker-text
3 long when = System.currentTimeMillis(); // notification time
4 Context context = getApplicationContext(); // application Context
5 CharSequence contentTitle = "My notification"; // message title
6 CharSequence contentText = "Hello World!"; // message text
7
8 Intent notificationIntent = new Intent(this, MyClass.class);
9 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
10
11 // the next two lines initialize the Notification, using the configurations above
12 Notification notification = new Notification(icon, tickerText, when);
13 notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
管理你的通知:
先实得到notificationmanager一个引用,代码如下:
1 String ns = Context.NOTIFICATION_SERVICE;
2 NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
当你想传递你的notification的时候,你需要使用notify(int , Notification)函数,这里的第一个参数很重要,就是你这个notification 在这个应用程序的唯一标识,当你需要更新你的通知(或许你的状态栏里的通知不止一个)或者用户饭回到你的应用(通过你在通知里定义的意图)时候你判断执行什么样的动作。
清除通知非常简单。你可以在定义你的Notification的时候添加"Flag_auto_cancel",你同样可以传递你的notification的id调用cancel(int),或者你可以试试cancelAll().
对通知添加声音,震动,灯光等就不细讲了,下面主要说说自定义通知。
默认情况下,包含标题和信息的通知会出现在你的通知窗口里。但是你也可以使用RemoteViews类来自定义一个layout显示你的通知。
首先,你得现定义你的通知布局文件,你自己随便定义一个custom_notification_layout.xml:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView android:id="@+id/textview"
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content"/>
10 <ProgressBar android:id="@+id/progress_bar"
11 style="@android:style/Widget.ProgressBar.Horizontal"
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:max="100"/>
15 </LinearLayout>
这个时候,你需要用到RemoteViews这个类来infalte这个layout文件。RemoteViews是一个描述了一个可以在另一个进程中显示的视图层次结构,并且提供了一些操作方法。设置完你remoteview之后,你就把它赋值给你的notification的contentView这个属性就可以了。下面是我些的一个service类,生成一个线程自动更新progressbar的值来提示给用户:
1 public class LocalService extends Service {
2 NotificationManager nManager = null;
3 Context context = null;
4 Notification notification = null;
5 private MyThread thread = null;
6 private static final int HELLO_ID = 1;
7 @Override
8 public void onCreate() {
9 // TODO Auto-generated method stub
10 Log.e("localservcie :------>", "onCreate");
11 context = getApplicationContext();
12 nManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
13
14 int icon = R.drawable.ic_launcher;
15 CharSequence tickerText = "通知";
16 long when = System.currentTimeMillis();
17 notification = new Notification();
18 notification.when = when;
19 notification.tickerText =tickerText;
20 notification.icon = icon;
21 super.onCreate();
22 }
23
24 @Override
25 public void onLowMemory() {
26 // TODO Auto-generated method stub
27 Log.e("localservcie :------>", "onLowMemory");
28 thread.stopThread();
29 nManager.cancel(HELLO_ID);
30 super.onLowMemory();
31 }
32
33 @Override
34 public void onDestroy() {
35 Log.e("localservcie :------>", "onDestroy");
36 thread.stopThread();
37 nManager.cancel(HELLO_ID);
38 super.onDestroy();
39 }
40
41 @Override
42 public void onRebind(Intent intent) {
43 // TODO Auto-generated method stub
44 super.onRebind(intent);
45 }
46
47 @Override
48 public int onStartCommand(Intent intent, int flags, int startId) {
49 // TODO Auto-generated method stub
50 Log.e("localservcie :------>", "onStartCommand");
51
52 thread = new MyThread();
53 thread.startThread();
54 return super.onStartCommand(intent, flags, startId);
55 }
56 @Override
57 public IBinder onBind(Intent intent) {
58 // TODO Auto-generated method stub
59 return null;
60 }
61 @Override
62 public boolean onUnbind(Intent intent) {
63 // TODO Auto-generated method stub
64 return super.onUnbind(intent);
65 }
66
67 private void update(int value){
68 RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
69 contentView.setTextViewText(R.id.textview, "xia zai ren wu 1");
70 contentView.setProgressBar(R.id.progress_bar, 100, value, false);
71 notification.contentView = contentView;
72 Intent notificationIntent = new Intent(context,NotificationActivity.class);
73 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
74 notification.contentIntent = pendingIntent;
75 nManager.notify(HELLO_ID, notification);
76 }
77
78 class MyThread implements Runnable{
79 private volatile Thread runner;
80
81 public synchronized void startThread(){
82 if(runner == null){
83 runner = new Thread(this);
84 runner.start();
85 }
86 }
87
88 public synchronized void stopThread(){
89 if(runner != null){
90 Thread moribund = runner;
91 runner = null;
92 moribund.interrupt();
93 }
94 }
95
96 public void run(){
97 while(Thread.currentThread() == runner){
98 //do stuff which can be interrupted if necessary
99 int value =10;
100 while(value<=100){
101 try {
102 Log.e("localservice->thread->run()", "run");
103 update(value);
104 Thread.sleep(1000);
105 value+=10;
106
107 } catch (InterruptedException e) {
108 Log.e("localservice->thread->run()", "InterruptedException");
109 return;
110 }
111 }
112 }
113 }
114
115 }
116
117
118 }
效果图如下: