我們在QQ項目中實現瞭通知欄後臺運行,以及來新消息提示,通常在消息通知時,我們經常用到兩個組件Toast和Notification。特別是重要的和需要長時間顯示的信息,用Notification就最合適不過瞭。當有消息通知時,狀態欄會顯示通知的圖標和文字,通過下拉狀態欄,就可以看到通知信息瞭,Android這一創新性的UI組件贏得瞭用戶的一致好評,就連蘋果也開始模仿瞭。其實有點類似於Windows的托盤顯示。
下面我們就來根據QQ小項目,來具體分析一下。先看下兩張效果圖:
一、通知欄的佈局文件,在我們這個QQ小項目中,當我們在好友列表的Activity按返回鍵的時候,先作一個程序進入後臺運行的標記(可以是全局變量,也可以保存到SharedPreferenced文件中),然後發送一個廣播,我們通過在服務裡接收這個廣播,就馬上初始化後臺運行的通知欄的view,當新消息到來時,我們就不把消息通過廣播發送出去瞭(因為沒有Activity在運行),而是直接通過更新通知欄來提醒用戶,同時發送一個通知(帶聲音、帶振動)。下面是我們這個在通知欄的view的佈局文件notify_view.xml:
[html]
<?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:
[java]
/**
* 創建通知
*/
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返回按鍵的廣播接收者,用戶按返回鍵發送廣播,並做好標記,程序進入後臺運行:
[java]
// 收到用戶按返回鍵發出的廣播,就顯示通知欄
private BroadcastReceiver backKeyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "QQ進入後臺運行", 0).show();
setMsgNotification();
}
};
四,通過handler更新通知欄,我們是通過handler來處理消息並更新通知欄的:
[java]
// 用來更新通知欄消息的handler
private 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文件中的,其實可以保存到應用的全局變量:
[java]
in.setMessageListener(new MessageListener() {
@Override
public void Message(TranObject msg) {
// System.out.println("GetMsgService:" + msg);
if (util.getIsStart()) {// <span style="color:#ff0000;">如果 是在後臺運行,就更新通知欄,否則就發送廣播給</span>Activity
if (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);// 把收到的消息已廣播的形式發送出去
}
}
});
後臺消息處理就是這樣實現的,如果大傢有什麼好的建議或者疑問,歡迎給我留言,謝謝。