FCM---Android系統(tǒng)級推送---你還在用第三方推送?

本文已授權(quán)微信公眾號 Android技術(shù)經(jīng)驗(yàn)分享 獨(dú)家發(fā)布

轉(zhuǎn)載請注明出處:FCM---Android系統(tǒng)級推送---你還在用第三方推送?

Firebase Cloud Messaging

FCM是谷歌推出的最新的Android系統(tǒng)級別的消息推送服務(wù)(用來替換GCM)。
GCM(Google Cloud Message for Android)是Google發(fā)布的Android服務(wù)器推送(push)技術(shù)。
之前的C2DM(Android Cloud to Device Messaging)已與2012年6月26日被正式棄用。

注:國內(nèi)可接收FCM推送,但必須安裝谷歌服務(wù)。具體操作請參考官方文檔。

官方文檔

Android端Demo地址


圖例

生命周期流程

下面是FCM的主要過程:

  1. Enabling FCM:運(yùn)行在手機(jī)上注冊了來接收消息的Android程序。
  2. Sending a message:發(fā)送消息到手機(jī)的第三方程序服務(wù)器。
  3. Receiving a message:從GCM服務(wù)器接收消息的Android程序。

Android端設(shè)置

  • 一項(xiàng)可以擴(kuò)展 FirebaseMessagingService 的服務(wù)。如果您希望在后臺進(jìn)行接收應(yīng)用通知之外的任何消息處理,則必須添加此服務(wù)。要在前臺應(yīng)用中接收通知、接收數(shù)據(jù)負(fù)載以及發(fā)送上游消息等,您必須擴(kuò)展此服務(wù)。
  • 一項(xiàng)可以擴(kuò)展 FirebaseInstanceIdService 的服務(wù),用于處理注冊令牌的創(chuàng)建、輪轉(zhuǎn)和更新。如果要發(fā)送至特定設(shè)備或者創(chuàng)建設(shè)備群組,則必須添加此服務(wù)。

通過替換 FirebaseMessagingService.onMessageReceived 方法,您可以根據(jù)收到的消息執(zhí)行操作,并獲取消息數(shù)據(jù):

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // ...
 
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());
 
    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
    }
 
    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }
 
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

檢查 Google Play 服務(wù) APK

實(shí)現(xiàn)連接服務(wù)器協(xié)議

Firebase Cloud Messaging服務(wù)器端包含兩個組件:

  1. GCM 連接服務(wù)器,由 Google 提供。這些服務(wù)器從一個應(yīng)用服務(wù)器獲取消息,并將其發(fā)送至在設(shè)備上運(yùn)行的客戶端應(yīng)用。Google 為 HTTP 和 XMPP 提供連接服務(wù)器。
  2. 一臺應(yīng)用服務(wù)器,您必須在您的環(huán)境中實(shí)現(xiàn)它。此應(yīng)用服務(wù)器通過選定的FCM連接服務(wù)器,使用合適的 XMPP 或 HTTP 協(xié)議向客戶端應(yīng)用發(fā)送數(shù)據(jù)。

實(shí)現(xiàn) HTTP 連接服務(wù)器協(xié)議

要對某個下游消息進(jìn)行尋址或"確定其目標(biāo)",應(yīng)用服務(wù)器需要將 to 設(shè)置為接收客戶端應(yīng)用的注冊令牌。您可以發(fā)送帶有預(yù)定義字段的通知消息或自定義數(shù)據(jù)消息;請參閱消息負(fù)載中的通知和數(shù)據(jù),了解關(guān)于負(fù)載支持的詳細(xì)信息。本頁中的示例用于說明如何通過 HTTP協(xié)議發(fā)送數(shù)據(jù)消息。

  • HTTP POST 請求
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
 
{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

高級消息傳遞選項(xiàng)

屬性 范例
Sender ID (發(fā)送者 ID) 819786133815
API Key (API 密鑰 ) AAAAvt8PsTc:APA91bFjsbsccwMDjxr7m04Fm9qEKVesfpm_3Gdy-9Wv_TC33nmi-9o6ksbUK1eK-TIyn9q6khLF7MHRSqj0DbxPyN4SVPZED0cEFE5E9ysz5VIZFZkOUHjuws7cKKfhSNhlQ9cYgL7kcdcjIOi7xYVYyyWSOjCaew
Registration Token (注冊令牌) 由 FCM SDK 為每個客戶端應(yīng)用實(shí)例生成的 ID。 單一設(shè)備和設(shè)備群組消息傳遞需要該令牌。請注意,注冊令牌必須保密。

通知

要發(fā)送通知,可設(shè)置 notification 鍵并針對通知消息的用戶可見部分設(shè)置必要的預(yù)定義鍵選項(xiàng)集。
例如,這是 IM 應(yīng)用中的 JSON 格式的通知消息。 用戶可能會在設(shè)備上看到標(biāo)題為"Portugal vs. Denmark"、文本為"great match!"的消息:

  • Authorization: key=AAAAvt8PsTc:APA91bFjsbsccwMDjxr7m04Fm9qEKVesfpm_3Gdy-9Wv_TC33nmi-9o6ksbUK1eK-
    TIyn9q6khLF7MHRSqj0DbxPyN4SVPZED0cEFE5E9ysz5VIZFZkOUHjuws7cKKfhSNhlQ9cYgL7kcdcjIOi7xYVYyyWSOjCaew
  • Content-Type: application/json
//單個客戶端使用令牌通知
 {
    "to" : "eNh8RzL09LY:APA91bEKwVeY-FGl_h-9oTZ7BZQJ79xR_EtPBpnoq3ecuPwTpbLWgrVaTuqjoakDZCuf0SVVsc5QbnOOAWYpHuLH7_QYiwT7LE2XMSA_rokM6NB0HlwfcuY-oYNnZsqxveumhg7tR0G2",
   "notification" : {
      "body" : "great match!",
      "title" : "Portugal vs. Denmark",
      "icon" : "myicon"
    }
  }

 {
    "to" : "eV1M0ZMn3Qc:APA91bHQiquRmGUPSuK8KaTf3N1tVMKp43WvX1TnPWSOVuHw6imb8digKv-yIRyESweHvkK7I8lNtzRllDSXb9WVswD9kX5dGUfs3uAH3U_m0qJxcHUe_F9YIiCwI3lTNnzP_TRlNw1-",
   "notification" : {
      "body" : "great match!",
      "title" : "Portugal vs. Denmark",
      "icon" : "myicon"
    }
  }

//多個客戶端通知,使用registration_ids數(shù)組
{
   "registration_ids" : ["eNh8RzL09LY:APA91bEKwVeY-FGl_h-9oTZ7BZQJ79xR_EtPBpnoq3ecuPwTpbLWgrVaTuqjoakDZCuf0SVVsc5QbnOOAWYpHuLH7_QYiwT7LE2XMSA_rokM6NB0HlwfcuY-oYNnZsqxveumhg7tR0G2",
    "eV1M0ZMn3Qc:APA91bHQiquRmGUPSuK8KaTf3N1tVMKp43WvX1TnPWSOVuHw6imb8digKv-yIRyESweHvkK7I8lNtzRllDSXb9WVswD9kX5dGUfs3uAH3U_m0qJxcHUe_F9YIiCwI3lTNnzP_TRlNw1-",
   "notification"]
  "notification" : {
      "body" : "是的。我成功了!",
      "title" : "Portugal vs. Denmark",
      "icon" : "myicon"
    }
  }

應(yīng)用在后臺運(yùn)行時,通知將會傳遞至通知托盤。 對于在后臺運(yùn)行的應(yīng)用,消息由下列回調(diào)處理:

  • iOS 上的 didReceiveRemoteNotification:
  • Android 上的 onMessageReceived()。數(shù)據(jù)包中的 notification 鍵包含通知。

設(shè)置消息優(yōu)先級

 "priority" : "high",

下游消息語法

官方文檔 : https://firebase.google.cn/docs/cloud-messaging/http-server-ref?hl=zh-cn#send-downstream

demo

http://www.lxweimin.com/p/5d1982dd588b

注意

當(dāng)firebase推送的時候,是分當(dāng)前應(yīng)用在前后臺兩種情況的。當(dāng)應(yīng)用在前臺的時候,消息到來的時候會響應(yīng)onMessageReceived函數(shù),你就可以在里面想怎么處理就怎么處理了。當(dāng)應(yīng)用在后臺或者被殺掉的時候,這個函數(shù)是不會響應(yīng)的,它會直接吧參數(shù)發(fā)送到啟動的Activity中,以下是google的文檔說明:

Handle messages in a backgrounded app

When your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.

This includes messages that contain both notification and data payload. In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.

處理方式:在后臺的情況下你需要在應(yīng)用的主Activity的onCreate方法中調(diào)用getIntent.getExtra()方法才能拿到推送到的參數(shù)

server 端建置

Google 稱開發(fā)者的 server 為 third party server,third party server 通常就是您的網(wǎng)站,至少要具備 2 個功能:
一是接收 Android 裝置上傳 GCM 註冊成功的 regId,
一是負(fù)責(zé)處理註銷 regId。

另外有個功能是用來發(fā)送訊息給 Android client 端 或 接收 client 端上傳的訊息,如果只有需要發(fā)送訊息的功能,那麼這支程式您可以放在您的網(wǎng)站(third party server)上 或是 放在公司內(nèi)某個部門的電腦內(nèi);如果還要接收 client 端上傳的訊息,那這支程式就得放在您的網(wǎng)站上。

要納入考慮的是,當(dāng)安裝您 app 的 Android 裝置數(shù)達(dá)成千上萬時,執(zhí)行網(wǎng)站上的 php 可能會有效率上的問題。

接收註冊的程式 gcm_register.php:

if(isset($_POST['regId']))
{
    $regId = $_POST['regId'];
    $sql = "INSERT INTO 資料表 (gcm_id,...) VALUES ('$regId',...)";
    $pdo->exec($sql);
}
 

GCM 運(yùn)作流程
安裝好的 app 第一次執(zhí)行時,app 會向 Google 註冊並取得 regId,app 成功取得 regId 後便將 regId 傳送給您網(wǎng)站 gcm_register.php,您可在 ADT 的 log 中看到取得的 regId;regId 長達(dá) 162 字元, 如果您想將 regId 儲存於資料庫系統(tǒng)內(nèi),則您需要建立一個 table 存放 Android 裝置傳上來的 regId,存放 regId 的欄位長度最好大於 162 字元,因?yàn)橐?Android 設(shè)備爆炸性成長的速度來看,如果愈來愈多開發(fā)人員採用 GCM,那麼 regId 長度勢必再增加...

當(dāng)您的網(wǎng)站(third party server) 接收並儲存註冊 GCM 成功的 regId,爾後您的網(wǎng)站便可以發(fā)送訊息到已註冊的 app。

當(dāng)您的 third party server 要發(fā)送訊息給有安裝您 app 的 Android 裝置時,您的 server 是將訊息發(fā)送給 Google GCM server,由 Google GCM server 再將訊息轉(zhuǎn)發(fā)給您 指定的 regId。

而當(dāng) Android 裝置解除安裝您的 app 時,Google GCM server 並不會立即通知您的 thrid party server,而是在下一次您發(fā)送訊息給該 Android 裝置時,Google GCM server 才會回應(yīng)給您的 third party server 錯誤,錯誤的內(nèi)容是該裝置並未註冊,所以您的 third party server 要在此時將該裝置的 regId 從您的資料庫中刪除。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,598評論 25 707
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,461評論 2 45
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,777評論 18 139
  • 你說 我的愛 是枷鎖 你想過屬于你的生活 你想自己嘗試不管對錯 是的 我心底愛你勝過愛我 ...
    七七行記閱讀 369評論 0 0
  • 文:迷妹喬小喵 大家對上班造型是什么印象,穿著漂亮又時尚的正裝,精致的妝容和那5-10 cm的恨天高。高跟鞋讓你的...
    迷妹喬小喵閱讀 489評論 0 1