1. 程式人生 > >Android裡的Xmpp的理解(訊息推送)

Android裡的Xmpp的理解(訊息推送)

 XMPP(可擴充套件通訊和表示協議)是基於可擴充套件標記語言(XML)的協議,它用於即時訊息(IM)以及線上探測。這個協議可能最終允許因特網使用者向因特網上的其他任何人傳送即時訊息。用xmpp來實現android的push功能,感覺有點大材小用了,xmpp本身是一種即時通訊協議。

  xmpp是一種用於即時通訊的協議,使用過程有點類似於我們使用QQ的過程,其使用過程分為三步:

  1. 連線伺服器,就好像開啟QQ軟體,看程式碼:

  1. if(!mXmppManager.isConnected()) {  
  2.     ConnectionConfiguration config = new
     ConnectionConfiguration(mHost, mPort);  
  3.     config.setSecurityMode(SecurityMode.required);  
  4.     config.setSASLAuthenticationEnabled(false);  
  5.     config.setCompressionEnabled(false);  
  6.     XMPPConnection connection = new XMPPConnection(config);  
  7.     mXmppManager.setConnection(connection);  
  8.     try
     {  
  9.         connection.connect();  
  10.         Log.i(LOGTAG, "XMPP connected successfully");  
  11.         /** 
  12.          * 這個就是對於通訊的xml文字進行解析的解析器,再把資訊轉換成IQ,這個相當於QQ的聊天資訊 
  13.          * 如果要用這個協議,其IQ的子類和IQProvider要進行重寫 
  14.          */
  15.         ProviderManager.getInstance().addIQProvider("notification",  
  16.                 "androidpn:iq:notification"
    ,  
  17.                 new NotificationIQProvider());  
  18.     } catch (XMPPException e) {  
  19.         Log.d(LOGTAG, "the connection is error ... ");  
  20.     }  
  21.     mXmppManager.runTask();  
  22. else {  
  23.     Log.i(LOGTAG, "XMPP connected already");  
  24.     mXmppManager.runTask();  
  25. }  

這一步主要是連線伺服器,還有設定一些連線的引數,還有設定連線的解析器。

  2. 如果沒有使用者,註冊新的帳號和密碼

  1. if(!mXmppManager.isRegistered()){  
  2.     final String newUsername = newRandomUUID();  
  3.     final String newPassword = newRandomUUID();  
  4.     Registration registration = new Registration();  
  5.     PacketFilter packetFilter = new AndFilter(new PacketIDFilter(  
  6.             registration.getPacketID()), new PacketTypeFilter(  
  7.             IQ.class));  
  8.     PacketListener packetListener = new PacketListener() {  
  9.         @Override
  10.         publicvoid processPacket(Packet packet) {  
  11.             // 伺服器回覆客戶端
  12.             if(packet instanceof IQ) {  
  13.                 IQ response = (IQ) packet;  
  14.                 if(response.getType() == IQ.Type.ERROR) { // 註冊失敗
  15.                     if (!response.getError().toString().contains(  
  16.                             "409")) {  
  17.                         Log.e(LOGTAG,"Unknown error while registering XMPP account! " + response.getError().getCondition());  
  18.                     }  
  19.                 } elseif(response.getType() == IQ.Type.RESULT) { // 註冊成功
  20.                     mXmppManager.setUsername(newUsername);  
  21.                     mXmppManager.setPassword(newPassword);  
  22.                     // 把使用者名稱和密碼都儲存到磁碟
  23.                     Editor editor = mSharedPrefs.edit();  
  24.                     editor.putString(Contants.XMPP_USERNAME, newUsername);  
  25.                     editor.putString(Contants.XMPP_PASSWORD, newPassword);  
  26.                     editor.commit();  
  27.                     mXmppManager.runTask();  
  28.                 }  
  29.             }  
  30.         }  
  31.     };  
  32.     // 給註冊的Packet設定Listener,因為只有等到正真註冊成功後,我們才可以交流
  33.     mConnection.addPacketListener(packetListener, packetFilter);  
  34.     registration.setType(IQ.Type.SET);  
  35.     registration.addAttribute("username", newUsername);  
  36.     registration.addAttribute("password", newPassword);  
  37.     // 向伺服器端,傳送註冊Packet包,注意其中Registration是Packet的子類
  38.     mConnection.sendPacket(registration);  
  39. else { // 已經註冊過了
  40.     mXmppManager.runTask();  
  41. }  

只要連線了伺服器了,客戶端就可以向伺服器端傳送訊息,傳送是以Packet(資料包)來進行傳送的,這個類有很多的子類,註冊的子類為Registration。

 還有要注意的是,上面的addPacketListener方法不是給所有傳送的資料包設定listener,而只是針對這次的註冊Packet。

  3. 用註冊的帳號和密碼進行登陸(像用QQ號帳進行登陸一樣)

  1. // 判斷是否已經登陸過了,是否是在登陸狀態
  2. if(!mXmppManager.isAuthenticated()) {  
  3.     try {  
  4.         mConnection.login(mUsername, mPassword, "AndroidpnClient");  
  5.         // 設定XmppConnection的監聽器
  6.         if(mXmppManager.getConnectionListener() != null) {  
  7.             mConnection.addConnectionListener(mXmppManager.getConnectionListener());  
  8.         }  
  9.         // 設定伺服器端推送的監聽器
  10.         PacketFilter packetFilter = new PacketTypeFilter(NotificationIQ.class);  
  11.         PacketListener packetListener = mXmppManager.getNotificationPacketListener();  
  12.         mConnection.addPacketListener(packetListener, packetFilter);  
  13.         mXmppManager.runTask();  
  14.     } catch (XMPPException e) {  
  15.         // 登陸失敗,應該重試 
  16.         String INVALID_CREDENTIALS_ERROR_CODE = "401";  
  17.         String errorMessage = e.getMessage();  
  18.         // 如果只是因為沒有註冊,則進行重新註冊
  19.         if (errorMessage != null && errorMessage.contains(INVALID_CREDENTIALS_ERROR_CODE)) {  
  20.             mXmppManager.reregisterAccount();   
  21.             return;  
  22.         }  
  23.         mXmppManager.startReconnectionThread();  
  24.     } catch (Exception e) { // 有可能mConnection都為空
  25.         Log.e(LOGTAG, "LoginTask.run()... other error");  
  26.         Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: " + e.getMessage());  
  27.         mXmppManager.startReconnectionThread(); // 啟動重連執行緒
  28.     }  
  29. else {  
  30.     mXmppManager.runTask();  
  31. }  

這裡設定了連線的監聽器mConnection.addConnectionListener(),連線過程中有可以連線突然中斷,連接出錯等等問題,要進行監聽。

  設定伺服器推送資訊的Listener,接收到資訊後,顯示給使用者。
  如果出錯的原因是401(無效的使用者名稱和密碼,則應該進行重新註冊,再連線)

對於伺服器push過來的資訊進行處理,是在PacketListener類裡面,這個接口裡,只要實現一個方法processPacket(Packet packet),從傳過來的Packet(資料包)裡獲取自己需要的資料:

  1. publicvoid processPacket(Packet packet) {  
  2.     if(packet instanceof NotificationIQ) {  
  3.         NotificationIQ notification = (NotificationIQ) packet;  
  4.         if(notification.getChildElementXML().contains("androidpn:iq:notification")) {  
  5.             String notificationId = notification.getId();  
  6.             String notificationApiKey = notification.getApiKey();  
  7.             String notificationTitle = notification.getTitle();  
  8.             String notificationMessage = notification.getMessage();  
  9.             String notificationUri = notification.getUri();  
  10.             Intent intent = new Intent(Contants.ACTION_SHOW_NOTIFICATION);  
  11.             intent.putExtra(Contants.NOTIFICATION_ID, notificationId);  
  12.             intent.putExtra(Contants.NOTIFICATION_API_KEY,notificationApiKey);  
  13.             intent.putExtra(Contants.NOTIFICATION_TITLE,notificationTitle);  
  14.             intent.putExtra(Contants.NOTIFICATION_MESSAGE, notificationMessage);  
  15.             intent.putExtra(Contants.NOTIFICATION_URI, notificationUri);  
  16.             mXmppManager.getContext().sendBroadcast(intent);  
  17.         }  
  18.     }  
  19. }  

相關推薦

AndroidXmpp理解(訊息)

 XMPP(可擴充套件通訊和表示協議)是基於可擴充套件標記語言(XML)的協議,它用於即時訊息(IM)以及線上探測。這個協議可能最終允許因特網使用者向因特網上的其他任何人傳送即時訊息。用xmpp來實現android的push功能,感覺有點大材小用了,xmpp本身是一種即時

AndroidpnXmpp理解(訊息)

XMPP(可擴充套件通訊和表示協議)是基於可擴充套件標記語言(XML)的協議,它用於即時訊息(IM)以及線上探測。這個協議可能最終允許因特網使用者向因特網上的其他任何人傳送即時訊息。用xmpp來實現android的push功能,感覺有點大材小用了,xmpp本身是一種即時通

Android 基於Netty的訊息方案之物件的傳遞(四)

在上一篇文章中《Android 基於Netty的訊息推送方案之字串的接收和傳送(三)》我們介紹了Netty的字串傳遞,我們知道了Netty的訊息傳遞都是基於流,通過ChannelBuffer傳遞的,那麼自然,Object也需要轉換成ChannelBuffer來傳遞。好在Netty本身已經給我們寫好了

Android 基於Netty的訊息方案之字串的接收和傳送(三)

在上一篇文章中《Android 基於Netty的訊息推送方案之概念和工作原理(二)》 ,我們介紹過一些關於Netty的概念和工作原理的內容,今天我們先來介紹一個叫做ChannelBuffer的東東。 ChannelBuffer  Netty中的訊息傳遞,都必須以位元

Android 基於Netty的訊息方案之概念和工作原理(二)

上一篇文章中我講述了關於訊息推送的方案以及一個基於Netty實現的一個簡單的Hello World,為了更好的理解Hello World中的程式碼,今天我來講解一下關於Netty中一些概念和工作原理的內容,如果你覺得本篇文章有些枯燥,請先去閱讀《Android 基於Netty的訊息推送方案之Hell

Android 基於Netty的訊息方案之Hello World(一)

訊息推送方案(輪詢、長連線) 輪詢 輪詢:比較簡單的,最容易理解和實現的就是客戶端去伺服器上拉資訊,資訊的及時性要求越高則拉資訊的頻率越高。客戶端拉資訊的觸發可以是一些事件,也可以是一個定時器,不斷地去查詢伺服器。所以這個方案的弊端也是顯而易見的,在輪詢的頻率較高時,伺服器

Android基於Netty的訊息方案(一)

訊息推送方案(輪詢、長連線) 輪詢 輪詢:比較簡單的,最容易理解和實現的就是客戶端去伺服器上拉資訊,資訊的及時性要求越高則拉資訊的頻率越高。客戶端拉資訊的觸發可以是一些事件,也可以是一個定時器,不斷地去查詢伺服器。所以這個方案的弊端也是顯而易見的,在輪詢的頻率較高時,

Android 整合友盟訊息

今天給夥伴們講解一下如何整合友盟的訊息推送 首先我們需要在友盟的官網註冊開發者賬號且建立一個訊息推送的運用 建立運用的時候包名就是咋們的程式包名 咋們這裡使用的是android studio 自動匯入模式(在app下的build.gradle裡面新增一下依賴)

Android開發-在Android應用整合友盟訊息SDK的實現(相容小米、華為、魅族機型離線

前 言 最近由於專案的功能需求的需要,需要在Android應用整合訊息推送的功能,而目前市面上的第三方訊息推送除了友盟推送外,還有極光推送、小米推送、個推以及信鴿(騰訊)推送等。當時本人對比各大第三方的訊息推送進行了測試,覺得友盟訊息推送整合簡單,推送訊息的

android訊息(二)之——XMPP協議

XMPP協議 XMPP協議,中文名為可擴充套件通訊和表示協議,是一種以XML為基礎的開放式實時通訊協議,它將需要實時通訊的訊息嵌入到XML結構體中,不僅具有很好的可擴充套件性,還有較強的可讀性。 XM

android 實現mqtt訊息,以及不停斷線重連的問題解決

前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &

基於Netty實現的Android 訊息(即時通訊)的解決方案

根據Netty框架實現訊息推送(即時聊天)功能. Netty框架,TCP長連線,心跳,阻塞訊息佇列,執行緒池處理訊息傳送, 基於Google ProtoBuf自定義的訊息協議, TCP粘包/拆包.... 客戶端通過TCP連線到伺服器,並建立TCP長連線;當伺服器端收到新訊息後通過TCP連線推送給

Android UDP - 簡單訊息功能

近期接觸了幾個小的Android開發專案,根據需求要利用到網路傳輸中的UDP協議方式傳輸,遇到不少坑,在此分享一下在Android應用中UDP的一些簡單技術功能實現,希望能幫到用得到的同僚。 需(wo)求(yao)分(gan)析(ma): 從PC上輸入一串亂七八糟,然後能在我手機(某為pow

Android安卓狀態列訊息通知(Notification)

我從不猜測,猜測是一個很壞的習慣——會影響正常的邏輯推理能力。              ——阿瑟·柯南·道爾 《福爾摩斯探案集》 近日,在做安卓專案開發的時候涉及到狀態列通知的需求,查了資料,總結一個簡

Android MQTT 訊息demo

··· 不會轉換gif格式,截圖給你們看看吧,如果有好的免費的轉換工具可以留言推薦給我,在此衷心感謝 裡邊寫了好多註釋,應該都能看懂,這個在ssm專案中也可以使用但需要定製,去除android化的東西 ··· 1.介面 2.連線Mqtt 3.傳送和接收訊息(上邊

Bmob 開發 Android程式快速入門 10 訊息

                             Bmob 開發 Android程式快速入門 10 訊息推送    

android開發 -- Notification 狀態列 訊息

這裡推薦下另一片文章:    Android 通知欄Notification的整合 全面學習 (一個DEMO讓你完全瞭解它) http://blog.csdn.net/vipzjyno1/article/details/25248021/ Notification

Android語音識別技術、訊息機制、二維碼掃描技術、NDK、JNI

一、常用資料結構:陣列,堆,棧,佇列,連結串列,樹,圖,散列表 陣列:把具有相同型別的若干變數按有序的形式組織起來。 堆:是一個特殊的樹形資料結構,每個結點都有一個值。一般說的堆是指二叉堆。他的最大特點就是根節點的值最小或最大,並且根節點的兩個子樹也是一個堆。 棧:只能在某

Android接入極光訊息

極光訊息推送: 極光推送(JPush)是一個端到端的推送服務,使得伺服器端訊息能夠及時地推送到終端使用者手機上,讓開發者積極地保持與使用者的連線 主要功能 保持與伺服器的長連線,以便訊息能夠即時推送到達客戶端 接收通知與自定義訊息,並向開發者App 傳遞

Android 根據訊息內容跳轉至指定頁面(極光

首先認識一下安卓newIntent方法的使用:newIntent方法的使用在於如果activity已經開啟了,並設定了啟動模式為:  android:launchMode="singleTask"的時候,當再次使用intent來啟動這個activtiy的時候就會進入這個方法裡