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

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



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

<?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" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"        android:padding="2dp" >        <RelativeLayout            android:layout_width="match_parent"            android:layout_height="wrap_content" >            <ImageView                android:id="@+id/notify_imageLog"                android:layout_width="40dp"                android:layout_height="40dp"                android:layout_alignParentLeft="true"                android:layout_centerVertical="true"                android:paddingLeft="5dp"                android:src="@drawable/h001" />            <TextView                android:id="@+id/notify_name"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerVertical="true"                android:layout_toRightOf="@+id/notify_imageLog"                android:paddingLeft="5dp"                android:text="name"                android:textColor="#000000"                android:textSize="20sp" />        </RelativeLayout>        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:orientation="horizontal" >            <TextView                android:id="@+id/notify_msg"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_weight="1"                android:paddingLeft="15dp"                android:text="msg"                android:textColor="@color/black"                android:textSize="15sp" />            <TextView                android:id="@+id/notify_time"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_weight="1"                android:gravity="right"                android:paddingRight="15dp"                android:text="time"                android:textColor="@color/black"                android:textSize="15sp" />        </LinearLayout>    </LinearLayout></LinearLayout>



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

/** * 创建通知 */private void setMsgNotification() {int icon = R.drawable.notify;CharSequence tickerText = "";long when = System.currentTimeMillis();mNotification = new Notification(icon, tickerText, when);// 放置在"正在运行"栏目中mNotification.flags = Notification.FLAG_ONGOING_EVENT;RemoteViews contentView = new RemoteViews(mContext.getPackageName(),R.layout.notify_view);contentView.setTextViewText(R.id.notify_name, util.getName());contentView.setTextViewText(R.id.notify_msg, "手机QQ正在后台运行");contentView.setTextViewText(R.id.notify_time, MyDate.getDate());// 指定个性化视图mNotification.contentView = contentView;Intent intent = new Intent(this, FriendListActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);// 指定内容意图mNotification.contentIntent = contentIntent;mNotificationManager.notify(Constants.NOTIFY_ID, mNotification);}


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

// 收到用户按返回键发出的广播,就显示通知栏private BroadcastReceiver backKeyReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubToast.makeText(context, "QQ进入后台运行", 0).show();setMsgNotification();}};


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

// 用来更新通知栏消息的handlerprivate Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case MSG:int newMsgNum = application.getNewMsgNum();// 从全局变量中获取newMsgNum++;// 每收到一次消息,自增一次application.setNewMsgNum(newMsgNum);// 再设置为全局变量TranObject<TextMessage> textObject = (TranObject<TextMessage>) msg.getData().getSerializable("msg");// System.out.println(textObject);if (textObject != null) {int form = textObject.getFromUser();// 消息从哪里来String content = textObject.getObject().getMessage();// 消息内容ChatMsgEntity entity = new ChatMsgEntity("",MyDate.getDateEN(), content, -1, true);// 收到的消息messageDB.saveMsg(form, entity);// 保存到数据库// 更新通知栏int icon = R.drawable.notify_newmessage;CharSequence tickerText = form + ":" + content;long when = System.currentTimeMillis();mNotification = new Notification(icon, tickerText, when);mNotification.flags = Notification.FLAG_NO_CLEAR;// 设置默认声音mNotification.defaults |= Notification.DEFAULT_SOUND;// 设定震动(需加VIBRATE权限)mNotification.defaults |= Notification.DEFAULT_VIBRATE;mNotification.contentView = null;Intent intent = new Intent(mContext,FriendListActivity.class);PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);mNotification.setLatestEventInfo(mContext, util.getName()+ " (" + newMsgNum + "条新消息)", content,contentIntent);}mNotificationManager.notify(Constants.NOTIFY_ID, mNotification);// 通知一下才会生效哦break;default:break;}}};


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

in.setMessageListener(new MessageListener() {@Overridepublic void Message(TranObject msg) {// System.out.println("GetMsgService:" + msg);if (util.getIsStart()) {// 如果 是在后台运行,就更新通知栏,否则就发送广播给Activityif (msg.getType() == TranObjectType.MESSAGE) {// 只处理文本消息类型// System.out.println("收到新消息");// 把消息对象发送到handler去处理Message message = handler.obtainMessage();message.what = MSG;message.getData().putSerializable("msg", msg);handler.sendMessage(message);}} else {Intent broadCast = new Intent();broadCast.setAction(Constants.ACTION);broadCast.putExtra(Constants.MSGKEY, msg);sendBroadcast(broadCast);// 把收到的消息已广播的形式发送出去}}});


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


更多相关文章

  1. Android(安卓)P应用适配指南
  2. Android 消息推送
  3. 第10章 后台默默地劳动者----------探究服务android
  4. 【android极光推送】—从客户端到后台,一文通吃
  5. 深入探索 Android(安卓)电量优化
  6. android DownloadManager广播事件:下载完成、通知栏点击事件
  7. 广播+ Service详解、通知和权限-Android基础知识整理
  8. 【腾讯bugly干货】关于 Android(安卓)N 那些你不知道的事儿
  9. Android接电话流程,JAVA部分

随机推荐

  1. android Manifest.xml选项
  2. The Saygus VPhone V1 clears FCC, Will
  3. Android修改屏幕亮度
  4. Android(安卓)Textview 超出最多字数省略
  5. 原文:Android(安卓)Theme XML
  6. Android预定义样式
  7. android数据库操作(二)
  8. android 调节屏幕亮度
  9. 如何为ListView设置分割线
  10. Android实现体重测量仪的源码