本來想說 GCM 的部分前面已經寫過粉多次了,不過既然有網友提問是否可以提供不需要 java code 的 sample project,那麼就乾脆一次大放送,把接收/發送一併寫在同一個 sample project 好了。
sample project 置放於此
基本上這個 project 是以 XE8 建立的,所以如果要改用 XE7 開啟的話,建議自行新增一個專案後,再把 uMain.xxx 加入。
project > options 的設定部分,需要調整的只有需要將 Receive push notification 設定為 true
專案本身的部分,則是利用 delphi 已經寫好的 Backend.PushDevice 機制,直接藉助 Kinvey,簡化需要撰寫的 code,這部分比在 XE5/XE6 的時代已經進步太多了
畫面上置放一個 TMemo,2 個 Button,一個 TPushEvent,最後就是一個 TKinveyProvider
把 PushEvent1.Provider 設定為 KinveyProvider1
再將 PushEvent1.AutoActivate 以及 PushEvent1.AutoRegisterDevice 設定為 false
source code 如下
unit uMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo, IPPeerClient, REST.Backend.PushTypes, System.JSON, REST.Backend.KinveyPushDevice, System.PushNotification, REST.Backend.KinveyProvider, Data.Bind.Components, Data.Bind.ObjectScope, REST.Backend.BindSource, REST.Backend.PushDevice, IdHTTP, IdSSLOpenSSL; type TForm1 = class(TForm) MemoToken: TMemo; btnGetToken: TButton; btnSendMsg: TButton; PushEvents1: TPushEvents; KinveyProvider1: TKinveyProvider; procedure btnGetTokenClick(Sender: TObject); procedure PushEvents1DeviceTokenReceived(Sender: TObject); procedure FormCreate(Sender: TObject); procedure btnSendMsgClick(Sender: TObject); procedure PushEvents1PushReceived(Sender: TObject; const AData: TPushData); private { Private declarations } FIdHTTP: TIdHTTP; FSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL; procedure InitialIndy; procedure SendTestMessage; public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} const MessageTemplate = '{' + ' "registration_ids" : ["%s"],' + ' "data" : {"message" : "%s"}' + '}'; procedure TForm1.btnGetTokenClick(Sender: TObject); begin PushEvents1.Active := True; end; procedure TForm1.btnSendMsgClick(Sender: TObject); begin if PushEvents1.DeviceToken = '' then begin Showmessage('請先執行 Get Token'); Exit; end else SendTestMessage; end; procedure TForm1.FormCreate(Sender: TObject); begin MemoToken.Lines.Clear; KinveyProvider1.AndroidPush.GCMAppID := 'your AppID'; end; procedure TForm1.InitialIndy; begin if FIdHTTP = nil then FIdHTTP := TIdHTTP.Create(nil); if FSSLIOHandler = nil then FSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); with FIdHTTP do begin IOHandler := FSSLIOHandler; HTTPOptions := []; Request.ContentType := 'application/json'; Request.CharSet := 'utf-8'; Response.ContentType := 'application/json'; end; end; procedure TForm1.PushEvents1DeviceTokenReceived(Sender: TObject); begin MemoToken.Lines.Add(PushEvents1.DeviceToken); end; procedure TForm1.PushEvents1PushReceived(Sender: TObject; const AData: TPushData); begin showmessage(adata.Message); end; procedure TForm1.SendTestMessage; var lRequest: TStringStream; lText : string; lResult : string; begin InitialIndy; with FIdHTTP do begin Request.CustomHeaders.Clear; Request.CustomHeaders.AddValue('Authorization', 'key=your Authorization Key'); lText := Format(MessageTemplate, [PushEvents1.DeviceToken, 'TestMsg:' + DateTimeToStr(Now)]); lRequest := TStringStream.Create(lText, TEncoding.UTF8); try lResult := Post('https://android.googleapis.com/gcm/send', lRequest); except on e:exception do begin Showmessage('發送 GCM 訊息發生錯誤:' + e.Message); end; end; end; end; end. |
其中 your AppID(SenderID) 與 your Authorization Key 需要填入你自己的,如果不知道這兩者所指為何,可以參考網友分享文
http://nkeegamedev.blogspot.tw/2013/01/gcm-gcm-api-key.html
另外粉重要的的一個部分,需要自行修改專案目錄中的 AndroidManifest.template.xml,在 <%activity%> 之後加一行
<service android:name="com.embarcadero.gcm.notifications.GCMIntentService" />
像這樣
不加的話,在 app 未曾開啟過的狀況下(app 不在背景),會無法收到訊息
如果一切順利,那麼你應該可以得到如下結果
to be continued...