Android之動態更新通知欄(QQ續四)

來源:互聯網
上載者:User

      我們在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);// 把收到的訊息已廣播的形式發送出去}}});

後台訊息處理就是這樣實現的,如果大家有什麼好的建議或者疑問,歡迎給我留言,謝謝。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.