? ? 由于谷歌服務在國內不能用,Android 的推送真是一大痛點,但也推動了國內一批做第三方服務的廠商。第三方推送做的比較好的有極光、個推、百度、友盟,經過比較之后,最后選擇了極光推送。其實這些第三方推送之間的差別并不太大,技術上都沒問題,能不能收到推送,關鍵還是看前端進程是不是還活著,這也是影響推送成功率的關鍵。從我們App來看,Android的成功率一直不高,還不到iOS的五分之一。
????前面說了,影響推送成功的關鍵是前端進程是否活著,App想要收到推送的話,就要一直在后臺運行,還有一些流氓軟件,為了長期在后臺運行,充分利用Android系統的開放性,無所不用其極,這也是早期Android給人體驗差的一個重要原因。后來Android系統加強了對后臺進程的限制,尤其是國內的手機廠商,在對付國產軟件方面,有很高的造詣,甚至有的手機廠商就只給微信開了特權,其他軟件到后臺幾分鐘就被殺掉或凍結了。這樣用戶體驗是上來了,但是對于推送來說,真是雪上加霜。
? ? 還好,小米、華為等手機廠商也意識到了這個問題,紛紛推出了自家的推送服務。想從根本上解決Android的問題,還得依賴這些廠商呀!2017年10月16日,工信部也聯合國內各大廠商和互聯網公司,發起成立了統一推送聯盟,致力于解決Android推送問題,統一推送標準,但估計看到成果還需要些時日,遠水解不了近渴。于是最近抽時間,研究了華為、小米、OPPO、VIVO這幾家國內主流廠商的服務。
? ? 通過對各家推送服務SDK的研究,將分別對每家的推送進行分析,最終給出整合意見。
????先放上各家推送服務傳送門:華為,小米,VIVO,OPPO。
?華為:
? ? 感覺華為推送的文檔比較少,可能跟他的功能太簡單有關。首先需要解釋下幾個名詞:Hms(華為移動服務),NC(通知中心)。通知欄推送:即常規的推送,消息抵達時由NC,或者是小米/VIVO/OPPO/等推送服務彈出通知欄。透傳:可簡單理解為格式自由定義,不彈起通知欄的推送,且透傳一般情況下需要在APP處于前后臺時才能收到。
????注意,HMS除了支持推送,還支持華為賬號登錄,華為支付等功能,你可以根據需要自由對接,但因為我們研究的方向問題,這里只講推送部分。其實在此之前,還有一個老版本的華為推送,但SDK升級后老推送就不再支持,文檔也不見了,且新老推送是不兼容的,你只能二選一。
? ? 新的華為推送服務不支持IOS,非華為手機使用華為推送SDK則需要APP各自建立長鏈接。在非華為手機上首次點開APP后,SDK會引導用戶下載華為HMS安裝,體驗比較差,所以不建議大家在非華為手機上使用該SDK,而且個人嘗試了下,雖然下載安裝了HMS,但未能在非華為手機成功收到token。
? ? 華為手機使用官方推送的好處是顯而易見的,殺掉APP通知欄依然可以收到通知,所有APP共享推送通道,手機更省電,但如果想要使用透傳功能,就需要手機處于前后臺狀態。另外即便是EMUI的手機,也不是接入了SDK就能接收推送了,文檔中寫到只有部分EMUI4.0和4.1的手機,以及5.0之后的手機才能收到NC服務,其次,刪除token和通知欄消息開關的api 在EMUI5.1以上的手機上才能起到效果。最后FAQ中有講到EMUI8.0目前有個系統底層關于通知欄的bug,請將工程buildVersion、targetVersion和compileVersion都改成26之前的版本。
? ? 那如何分辨手機是否支持華為推送呢,官方FAQ提供了幾個方法,點開“在線幫助”-“常見問題說明”中,有具體的EMUI版本及HMS版本的識別方法,這里不再復述。
????服務端API調用有流控限制,用戶短時間內發送大量的消息會被流控,并返回HTTP 503狀態碼。默認3000條/秒,如需要調整,請聯系華為客服。并且每次API調用攜帶的device_token_list最大為1000個推送量,如果你的推送是群發則不用理會這個限制。
? ? 查看文檔時,請著重看“開發準備”,和“客戶端開發指南”,兩處的文檔描述很詳細。
? ? 集成SDK時還有一點需要注意,除了使用gradle集成SDK,還需要下載一個hms agent壓縮包,這個壓縮包其實就是一些華為的代碼,可能官方覺得把所有功能都整合到SDK里太大了,就用這種方式希望大家按需解壓,但個人感覺其實沒什么必要。解壓后的根目錄中有readme文件,建議仔細閱讀,如果你是windows,請點擊bat文件,執行后根據提示按需選擇即可,最終把提取出來的java文件放入工程目錄里。
? ? 在完成開發者賬號申請,創建APP,集成SDK,修改manifest等準備工作后,你就可以嘗試推送一條消息給手機了。
? ? 其實接入推送SDK,我們開發人員關心的無非三件事,一是如何獲取token/regid,二是通知消息怎么回調,三是推送格式怎么寫。
? ? 首先token方面,華為SDK是異步獲取,即調用gettoken方法后,方法內部最多只返回成功失敗的狀態碼,只有在自定義消息接收器里才能收到token值。而我們常用的極光SDK,則是同步方法:getregid,直接返回空或者具體值。這是他們之間的差異。
? ? 接下來說下華為推送消息回調,這里有些坑需要注意。目前自定義的接收器,只能接受兩個回調信息,onEvent和onPushMsg,前者是通知欄消息的回調,后者是透傳的回調。但通知欄回調在通知消息到達時是無法收到的,無論前后臺都不行,只有用戶點擊了攜帶附加消息的通知,onEvent才能觸發正常,而透傳之前說過了,必須在前后臺狀態才可以,所以如果大家收不到推送到達的回調,不要著急,SDK就是這樣設計的。
? ? 其實接入到這里,感覺華為這個推送SDK設計的很別扭,相信很多開發者是需要收到推送的時候在APP執行一些操作的,但是華為的推送不支持,用戶不點擊通知欄,即便應用處于前臺,你也永遠不知道這條推送到達了。所以如果大家用推送到達的回調來處理一些業務邏輯的話,建議發送通知欄消息的時候,再疊加一條透傳用于業務處理。
? ? 而推送格式方面,華為支持比較有限,通知欄推送只能指定打開APP(即首頁,大部分APP首頁都是閃屏),或者打開特定頁面,不夠靈活。譬如我們的使用場景是根據接受的推送信息分別跳轉至ABC等頁面,使用極光就可以自己在receiver里自由處理,而華為只能用兩種方式,一是指定通知欄點擊動作為打開APP,同時對scheme添加附加信息或對推送添加extra,在啟動頁根據獲取到的附加信息進行處理;二是按照scheme協議的格式,在我們的app的manifest里每個要跳轉的頁面都加入scheme,后臺推送時候針對發送即可。或者將兩個思路融合,創建一個透明樣式的activity,每次推送我們都指向該頁面,然后再解析附加信息按需跳轉即可。而且用這種方式的好處是不用在onEvent里處理回調。
小米:
? ? 小米文檔感覺非常詳細全面,閱讀完之后感覺和極光差不多,如果你熟悉極光推送,那么小米推送接入的應該會很快,而且原有邏輯部分幾乎不需要修改。小米推送的優勢是,在MIUI中所有APP共享推送通道,APP被殺死也依然能收到通知,除此之外還支持u3d,python等sdk,還有花哨的呼吸燈等推送配置。而且小米推送也是支持IOS的,所以理論上,如果你沒有使用其他的統計崩潰統計等功能的話,完全可以用小米推送替換掉極光,友盟等。
? ? 因為小米文檔十分完善,這里直接從系統判斷,token獲取,回調方式,推送格式四方面分析。
? ? 判斷MIUI,直接在文檔中心搜索“如何識別小米設備/MIUI系統”即可,官方文檔會告訴你答案。
? ? token上,小米提供了同步的MiPushClient.getRegId的同步方法,以及recevier接收兩種方式。使用比較靈活。
? ? 消息回調上,onNotificationMessageArrived在推送消息到達時觸發,onNotificationMessageClicked則在用戶點擊通知欄時觸發,onReceivePassThroughMessage在透傳消息到達時觸發,但是需要注意,透傳依然需要APP處于前后臺狀態時候才能回調。而通知欄消息到達回調,只有APP在前后臺才能收到,在APP殺死后重啟,不再能回調成功。
? ? 推送格式上,小米除了提供了像華為一樣的,打開APP,打開指定頁面(scheme格式)外,還有自定義模式,自定義模式就是用戶點擊通知欄后,打不打開頁面,打開什么頁面,完全由開發者在receiver收到回調后自己處理。
? ? 另外,小米推送的功能比華為強大不少,支持分組,別名等功能。后臺API調用次數按照文檔說法,目前沒有限制,但是如果是針對regid推送,每次API調用最多只能攜帶1000個。
VIVO:
? ? ? vivo的推送文檔是pdf格式,需要下載。按照文檔,vivo推送目前只支持自家rom,而在token獲取,回調,推送格式上,和極光小米也是類似的。
? ? 但是對于vivo推送,有一些需要注意,點我--push推送--push接入FAQ中,有幾個關鍵點,一個是目前vivo推送不支持接入金融類服務!二是支持vivo push的vivo 機型特別少,對,你沒看錯,vivo自己家的推送服務,就支持那幾款手機而已。
? ? 不過SDK提供了識別手機是否支持vivo推送的方法,使用PushClient.getInstance(application).isSupport()或者是判斷回調狀態碼101均可。經個人嘗試,找到了若干款型號類似的手機,譬如文檔中講支持VIVO X21手機,但是我用X21A就不支持推送,可見這個局限性還挺大。因為找不到符合條件的手機,目前只是把代碼整合進去了,具體還沒進行測試。
????token獲取提供了PushClient.getInstance(application).getRegId()同步方法,onReceiveRegId回調方法,但文檔描述這個回調僅僅在regid變化時可收到。
? ??onNotificationMessageArrived回調在推送到達時觸發,onNotificationMessageClicked回調在推送點擊時觸發,因為沒有真機測試成功,在殺死APP重啟后是否能繼續收到未經驗證。
? ? 而且即便大家整合完畢,也需要留意,官方文檔中描述,VIVO推送是分時段的,為了避免打擾用戶,目前vivo手機接收的消息為9:00-21:00,服務器允許推送時間為9:00-20:00,單推不受此時間限制。限制時間外的推送將被作廢,不再重發。所以需要整合的小伙伴要權衡。
OPPO:
? ? oppo推送目前處于公測階段,打開就會提示只對部分開發者開放,至于如何成為部分受邀開發者,需要通過郵件進行申請,但是到哪里申請不知道。這里也沒有往下進行了。但想到OV(OPPO和VIVO,以下簡稱OV)其實是一個老板,而且看VIVO那邊的情況,差不多也就明白了,OV的推送服務應該是剛開始起步,估計只有部分新款手機才能支持,雖然OV手機的用戶占比比較高,但是能收到推送的新機型比例應該還是很低的。所以目前是否需要接入看大家各自需要。
推送整合 :
? ? 老牌三方推送,極光SDK也支持各家推送通道進行整合,就類似sharedsdk整合分享原理一樣,前提是需要分別注冊各家大廠的推送賬號,創建應用。最后按極光的文檔配置各種appid,appkey即可,但是極光的該功能是收費服務,具體費用需要咨詢極光商務。而自己整合肯定沒有費用問題。
? ? 單獨接入各家SDK的最終目的還是要整合在一起,按照目前的粗略調查,OV的ROM占比高達45%以上,還是很可觀的,如果加上華為,小米,四家廠商的ROM會高達85%+,整合后的效果會比單純集成極光好很多。魅族也有推送,但是比例低于1%,三星及其它手機則更低,所以就沒有關注其他的推送。
????整合的意義在于提高推送到達率,更加省電。?由于目前的OV推送服務有很大的不確定性,建議不是特別緊急就不用集成了,保持關注即可,畢竟隨著時間的推移,支持OV推送的手機比例會大幅度增加,屆時再接入也不遲。
? ? 目前整合的大致思路是首先識別ROM,依據rom類型分別啟動不同SDK(前邊已經介紹了各個廠商識別自家ROM的方法),如果無法成功識別或者啟動SDK異常,則使用極光等三方推送或小米推送作為兜底。
? ? 第二是獲取不同廠家的token/regid,上報給自己的服務器進行綁定,因為有的廠家是異步,有的是同步獲取,需要大家視情況自己處理業務邏輯。
? ? 第三由服務器針對APP上報的信息,使用不同廠家的推送API推送信息。推送方式和格式上建議統一,即創建一個透明activity,統一使用scheme格式并攜帶附加信息,看起來大概是這個樣子:你定義的scheme:你定義的host?action=你定義的action,然后在透明的activity里根據action跳轉至不同頁面,處理完成后及時關閉這個透明界面即可。
? ? 至此整個SDK集成的分析就結束了,今后可能會對此文檔不定期更新,感謝閱讀。