在Android手機平台上,Google提供了C2DM(Cloudto Device Messaging)服務,起初我就是准備采用這個服務來實現自己手機上的推送功能。
Android Cloud to Device Messaging (C2DM)是一個用來幫助開發者從服務器向Android應用程序發送數據的服務。該服務提供了一個簡單的、輕量級的機制,允許服務器可以通知移動應用程序直接與服務器進行通信,以便於從服務器獲取應用程序更新和用戶數據。C2DM服務負責處理諸如消息排隊等事務並向運行於目標設備上的應用程序分發這些消息。
但是經過一番研究發現,這個服務存在很大的問題:
1)C2DM內置於Android的2.2系統上,無法兼容老的1.6到2.1系統;
2)C2DM需要依賴於Google官方提供的C2DM服務器,由於國內的網絡環境,這個服務經常不可用,如果想要很好的使用,我們的App Server必須也在國外,這個恐怕不是每個開發者都能夠實現的;
有了上述兩個使用上的制約,導致我最終放棄了這個方案,不過我想利用另外一篇文章來詳細的介紹C2DM的框架以及客戶端和App Server的相應設置方法,可以作為學習與參考之用。
即然C2DM無法滿足我們的要求,那麼我們就需要自己來實現Android手機客戶端與App Server之間的通信協議,保證在App Server想向指定的Android設備發送消息時,Android設備能夠及時的收到。下面我來介紹幾種常見的方案:
1)輪詢:應用程序應當階段性的與服務器進行連接並查詢是否有新的消息到達,你必須自己實現與服務器之間的通信,例如消息排隊等。而且你還要考慮輪詢的頻率,如果太慢可能導致某些消息的延遲,如果太快,則會大量消耗網絡帶寬和電池。
2)SMS:在Android平台上,你可以通過攔截SMS消息並且解析消息內容來了解服務器的意圖。這是一個不錯的想法,我就見過采用這個方案的應用程序。這個方案的好處是,可以實現完全的實時操作。但是問題是這個方案的成本相對比較高,你很難找到免費的短消息發送網關,關於這個方案的實現,可以參考如下鏈接:https://labs.ericsson.com/apis/mobile-java-push/。
3)持久連接:這個方案可以解決由輪詢帶來的性能問題,但是還是會消耗手機的電池。Apple的推送服務之所以工作的很好,是因為每一台手機僅僅保持一個與服務器之間的連接,事實上C2DM也是這麼工作的。不過這個方案也存在不足,就是我們很難在手機上實現一個可靠的服務。Android操作系統允許在低內存情況下殺死系統服務,所以你的通知服務很可能被操作系統Kill掉了。
前兩個方案存在明顯的不足,第三個方案也有不足,不過我們可以通過良好的設計來彌補,以便於讓該方案可以有效的工作。畢竟,我們要知道GMail,GTalk以及GoogleVoice都可以實現實時更新的。
<!--[if !supportLists]--> ? <!--[endif]-->采用MQTT協議實現Android推送
MQTT是一個輕量級的消息發布/訂閱協議,它是實現基於手機客戶端的消息推送服務器的理想解決方案。
我們可以從這裡下載該項目的實例代碼,並且可以找到一個采用PHP書寫的服務器端實現。
架構如下所示:
wmqtt.jar 是IBM提供的MQTT協議的實現。你可以從如下站點下載它。你可以將該jar包加入你自己的Android應用程序中。
Really Small Message Broker (RSMB) ,他是一個簡單的MQTT代理,同樣由IBM提供。缺省打開1883端口,應用程序當中,它負責接收來自服務器的消息並將其轉發給指定的移動設備。
SAM是一個針對MQTT寫的PHP庫。你可以從這個下載它.
send_mqtt.php是一個通過POST接收消息並且通過SAM將消息發送給RSMB的PHP腳本。
實例代碼:
可以從GitHub上下載實例應用。運行該應用以後,通過手機浏覽器訪問http://tokudu.com/demo/android-push/,在第一個輸入框輸入設備ID,在第二個輸入框輸入想要發送的消息內容,按下“Send Push Message”按鈕,你就應該可以看到手機上收到了通知了。你也可以從這個GitHub地址上下載android-push源代碼,它包含了send_mqtt.php腳本。
采用XMPP協議實現Android推送