前面把聊天的基本功能都實現了,最近有點忙,因爲快到學期末了,考試就來了,所以後面可能會慢點。大家都反映沒有消息提醒,所以抽了點時間把聊天的提醒簡單的實現了下,下面簡單的介紹下。
原理
我這裏用到得原理主要就兩個知識點
- Notification
- BadgeView
只要你解決了這兩項以後的消息提醒神馬的都能輕鬆搞定。首先來解釋下他們的應用,對於Notification我想應該很多都接觸了,但還是簡單的說下,我這裏使用它就是實現我們日常看到的消息通知框的出現,不過其中的使用要注意幾點,下面會詳細指出。至於BadgeView這是一個開源庫,它的功能就是我們日常看到的在應用中顯示的未讀消息數。
原理介紹完了下面來看看實現
通知欄的顯示
這裏除了Notification還有一個重要的是PendingIntent(延遲意圖)就是實現點擊通知欄後的操作
延遲意圖PendingIntent
既然是意圖自然要使用Intent指定我們點擊後的應用操作
配置Intent
Intent intent = new Intent(App.getAppContext(), MainActivity.class);
//防止開啓重複的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
//防止pendingIntent相同
intent.setData(Uri.parse("message://" + regId));
bundle.putInt("_id", _id);
intent.putExtras(bundle);
我這裏是點擊都自動跳轉到主界面,然後在主界面做相應的操作。在這裏要注意下我前面說的注意點。
注意點
第一點
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
這句代碼是防止我們點擊通知欄後開啓指定的界面,後退棧時界面重複。如果你沒有清空棧,就會出現重複創建的現象。可能這裏有人會說可以使用launchMode的模式,沒錯當我們使用signalTop或者其它的如singleTask能解決重複界面的創建,但是這裏有個問題如signalTop當在棧頂是並不會重新創建該Activity而是會直接複用原來的。所以這樣就會導致頁面不會更新未讀消息數。
第二點
intent.setData(Uri.parse("message://" + regId));
爲intent設置不同的數據源,雖然PendingIntent提供了四個這方面的參數,但都是針對相同對象的延遲意圖
- FLAG_ONE_SHOT
意思就是你設置的延遲意圖只可使用一次,說明以後通過它的都不會實現
- FLAG_NO_CREATE
這個更簡單了就是不存在也就不會創建了直接返回null
- FLAG_CANCEL_CURRENT
這個就是存在就取消原來的,使用新的,新的只改變要傳遞的數據
- FLAG_UPDATE_CURRENT
跟上面的相差不大,它會更新原來的數據
上面的對要開啓不同的界面都沒有作用,都會覆蓋原來的意圖,導致不同的人發送消息時,點擊通知欄的不同通知顯示同一個聊天界面。這裏使用regId做唯一標識就能消除這方面的問題。
創建PendingIntent
PendingIntent pi = PendingIntent.getActivity(App.getAppContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
通知Notification構建
這裏我就直接貼代碼了都是很容易理解的了。
Notification notification = new Notification.Builder(App.getAppContext())
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setTicker("高仿微信有新消息")
.setContentTitle(userName)
.setContentText("[" + unReadNum + "條] " + rMessage)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
.setContentIntent(pi)
.setWhen(System.currentTimeMillis())
.build();
發送通知
獲取系統通知管理
manager = (NotificationManager) App.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
發送通知
manager.notify(_id, notification);
通知欄的構建就完美結束了
消息數的顯示
既然前面都說了藉助了開源庫,所以實現就相對來說就簡單了,我這裏把它總結成三步
創建BadgeView實例
BadgeView badgeView = new BadgeView(context, view);
其中view代表你要依附的視圖
構建文本
badgeView.setTextColor(Color.WHITE);
badgeView.setText(textValue);
badgeView.setBackground(context.getResources().getDrawable(R.drawable.dot_bg));
badgeView.setTextSize(12);
badgeView.setBadgePosition(BadgeView.POSITION_TOP_RIGHT);
badgeView.setBadgeMargin(0, 0);
上面的肯定沒問題吧,簡單明瞭,顯示位置badgeView.setBadgePosition
默認是右上角,但我感覺效果不明顯,不是我們要得效果,沒有像微信那樣視圖出去了部分,所以我都後面看了下源碼,發現了badgeView.setBadgeMargin(0, 0);
能使該效果明顯些。
顯示
badgeView.show();
到這裏所有的消息提醒功能就完成了,最後看下效果
效果圖
一系列文章
Android高仿微信之mvp實現(一)
Android高仿微信之mvp實現(二)
Android高仿微信之mvp實現(三)