Android之动态更新通知栏

我们在QQ项目中实现了通知栏后台运行,以及来新消息提示,通常在消息通知时,我们经常用到两个组件Toast和Notification。特别是重要的和需要长时间显示的信息,用Notification就最合适不过了。当有消息通知时,状态栏会显示通知的图标和文字,通过下拉状态栏,就可以看到通知信息了,Android这一创新性的UI组件赢得了用户的一致好评,就连苹果也开始模仿了。其实有点类似于Windows的托盘显示。

下面我们就来根据QQ小项目,来具体分析一下。先看下两张效果图:

Android之动态更新通知栏_第1张图片Android之动态更新通知栏_第2张图片


一、通知栏的布局文件,在我们这个QQ小项目中,当我们在好友列表的Activity按返回键的时候,先作一个程序进入后台运行的标记(可以是全局变量,也可以保存到SharedPreferenced文件中),然后发送一个广播,我们通过在服务里接收这个广播,就马上初始化后台运行的通知栏的view,当新消息到来时,我们就不把消息通过广播发送出去了(因为没有Activity在运行),而是直接通过更新通知栏来提醒用户,同时发送一个通知(带声音、带振动)。下面是我们这个在通知栏的view的布局文件notify_view.xml:

[html]  view plain  copy
  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.     <LinearLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:orientation="vertical"  
  11.         android:padding="2dp" >  
  12.   
  13.         <RelativeLayout  
  14.             android:layout_width="match_parent"  
  15.             android:layout_height="wrap_content" >  
  16.   
  17.             <ImageView  
  18.                 android:id="@+id/notify_imageLog"  
  19.                 android:layout_width="40dp"  
  20.                 android:layout_height="40dp"  
  21.                 android:layout_alignParentLeft="true"  
  22.                 android:layout_centerVertical="true"  
  23.                 android:paddingLeft="5dp"  
  24.                 android:src="@drawable/h001" />  
  25.   
  26.             <TextView  
  27.                 android:id="@+id/notify_name"  
  28.                 android:layout_width="wrap_content"  
  29.                 android:layout_height="wrap_content"  
  30.                 android:layout_centerVertical="true"  
  31.                 android:layout_toRightOf="@+id/notify_imageLog"  
  32.                 android:paddingLeft="5dp"  
  33.                 android:text="name"  
  34.                 android:textColor="#000000"  
  35.                 android:textSize="20sp" />  
  36.         </RelativeLayout>  
  37.   
  38.         <LinearLayout  
  39.             android:layout_width="fill_parent"  
  40.             android:layout_height="wrap_content"  
  41.             android:layout_gravity="center"  
  42.             android:orientation="horizontal" >  
  43.   
  44.   
  45.             <TextView  
  46.                 android:id="@+id/notify_msg"  
  47.                 android:layout_width="wrap_content"  
  48.                 android:layout_height="wrap_content"  
  49.                 android:layout_weight="1"  
  50.                 android:paddingLeft="15dp"  
  51.                 android:text="msg"  
  52.                 android:textColor="@color/black"  
  53.                 android:textSize="15sp" />  
  54.   
  55.             <TextView  
  56.                 android:id="@+id/notify_time"  
  57.                 android:layout_width="wrap_content"  
  58.                 android:layout_height="wrap_content"  
  59.                 android:layout_weight="1"  
  60.                 android:gravity="right"  
  61.                 android:paddingRight="15dp"  
  62.                 android:text="time"  
  63.                 android:textColor="@color/black"  
  64.                 android:textSize="15sp" />  
  65.         </LinearLayout>  
  66.     </LinearLayout>  
  67.   
  68. </LinearLayout>  



二、初始化通知栏view的方法,在GetMsgService中写一个方法,初始化我们这个通知栏的view:

[java]  view plain  copy
  1. /** 
  2.      * 创建通知 
  3.      */  
  4.     private void setMsgNotification() {  
  5.         int icon = R.drawable.notify;  
  6.         CharSequence tickerText = "";  
  7.         long when = System.currentTimeMillis();  
  8.         mNotification = new Notification(icon, tickerText, when);  
  9.   
  10.         // 放置在"正在运行"栏目中  
  11.         mNotification.flags = Notification.FLAG_ONGOING_EVENT;  
  12.   
  13.         RemoteViews contentView = new RemoteViews(mContext.getPackageName(),  
  14.                 R.layout.notify_view);  
  15.         contentView.setTextViewText(R.id.notify_name, util.getName());  
  16.         contentView.setTextViewText(R.id.notify_msg, "手机QQ正在后台运行");  
  17.         contentView.setTextViewText(R.id.notify_time, MyDate.getDate());  
  18.         // 指定个性化视图  
  19.         mNotification.contentView = contentView;  
  20.   
  21.         Intent intent = new Intent(this, FriendListActivity.class);  
  22.         PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,  
  23.                 intent, PendingIntent.FLAG_UPDATE_CURRENT);  
  24.         // 指定内容意图  
  25.         mNotification.contentIntent = contentIntent;  
  26.         mNotificationManager.notify(Constants.NOTIFY_ID, mNotification);  
  27.     }  


三,好友列表Activity返回按键的广播接收者,用户按返回键发送广播,并做好标记,程序进入后台运行:

[java]  view plain  copy
  1. // 收到用户按返回键发出的广播,就显示通知栏  
  2.     private BroadcastReceiver backKeyReceiver = new BroadcastReceiver() {  
  3.   
  4.         @Override  
  5.         public void onReceive(Context context, Intent intent) {  
  6.             // TODO Auto-generated method stub  
  7.             Toast.makeText(context, "QQ进入后台运行"0).show();  
  8.             setMsgNotification();  
  9.         }  
  10.     };  


四,通过handler更新通知栏,我们是通过handler来处理消息并更新通知栏的:

[java]  view plain  copy
  1. // 用来更新通知栏消息的handler  
  2.     private Handler handler = new Handler() {  
  3.         public void handleMessage(Message msg) {  
  4.             switch (msg.what) {  
  5.             case MSG:  
  6.                 int newMsgNum = application.getNewMsgNum();// 从全局变量中获取  
  7.                 newMsgNum++;// 每收到一次消息,自增一次  
  8.                 application.setNewMsgNum(newMsgNum);// 再设置为全局变量  
  9.                 TranObject<TextMessage> textObject = (TranObject<TextMessage>) msg  
  10.                         .getData().getSerializable("msg");  
  11.                 // System.out.println(textObject);  
  12.                 if (textObject != null) {  
  13.                     int form = textObject.getFromUser();// 消息从哪里来  
  14.                     String content = textObject.getObject().getMessage();// 消息内容  
  15.   
  16.                     ChatMsgEntity entity = new ChatMsgEntity("",  
  17.                             MyDate.getDateEN(), content, -1true);// 收到的消息  
  18.                     messageDB.saveMsg(form, entity);// 保存到数据库  
  19.   
  20.                     // 更新通知栏  
  21.                     int icon = R.drawable.notify_newmessage;  
  22.                     CharSequence tickerText = form + ":" + content;  
  23.                     long when = System.currentTimeMillis();  
  24.                     mNotification = new Notification(icon, tickerText, when);  
  25.   
  26.                     mNotification.flags = Notification.FLAG_NO_CLEAR;  
  27.                     // 设置默认声音  
  28.                     mNotification.defaults |= Notification.DEFAULT_SOUND;  
  29.                     // 设定震动(需加VIBRATE权限)  
  30.                     mNotification.defaults |= Notification.DEFAULT_VIBRATE;  
  31.                     mNotification.contentView = null;  
  32.   
  33.                     Intent intent = new Intent(mContext,  
  34.                             FriendListActivity.class);  
  35.                     PendingIntent contentIntent = PendingIntent.getActivity(  
  36.                             mContext, 0, intent, 0);  
  37.                     mNotification.setLatestEventInfo(mContext, util.getName()  
  38.                             + " (" + newMsgNum + "条新消息)", content,  
  39.                             contentIntent);  
  40.                 }  
  41.                 mNotificationManager.notify(Constants.NOTIFY_ID, mNotification);// 通知一下才会生效哦  
  42.                 break;  
  43.   
  44.             default:  
  45.                 break;  
  46.             }  
  47.         }  
  48.     };  


 

四,监听消息,我们监听收消息线程中收到的消息先判断程序是否运行在后台,如果在后台,我们就直接把消息发送给handler,如果不是,就通过广播发送出去这个消息,所以:我们首先需要在按返回键的进入后台的时候,做一个标记,表示程序进入后台运行,我这里是通过保存在SharedPreferenced文件中的,其实可以保存到应用的全局变量:

[java]  view plain  copy
  1. in.setMessageListener(new MessageListener() {  
  2.   
  3.                 @Override  
  4.                 public void Message(TranObject msg) {  
  5.                     // System.out.println("GetMsgService:" + msg);  
  6.                     if (util.getIsStart()) {// <span style="color:#ff0000;">如果 是在后台运行,就更新通知栏,否则就发送广播给</span>Activity  
  7.                         if (msg.getType() == TranObjectType.MESSAGE) {// 只处理文本消息类型  
  8.                             // System.out.println("收到新消息");  
  9.                             // 把消息对象发送到handler去处理  
  10.                             Message message = handler.obtainMessage();  
  11.                             message.what = MSG;  
  12.                             message.getData().putSerializable("msg", msg);  
  13.                             handler.sendMessage(message);  
  14.                         }  
  15.                     } else {  
  16.                         Intent broadCast = new Intent();  
  17.                         broadCast.setAction(Constants.ACTION);  
  18.                         broadCast.putExtra(Constants.MSGKEY, msg);  
  19.                         sendBroadcast(broadCast);// 把收到的消息已广播的形式发送出去  
  20.                     }  
  21.                 }  
  22.             });  


后台消息处理就是这样实现的,如果大家有什么好的建议或者疑问,欢迎给我留言,谢谢。


你可能感兴趣的:(notification)