標籤:
delphi 10 裡面的安卓服務有四種,上面的一篇文章裡面的圖有介紹。
今天做一個remote service 的例子。(裡面一部分代碼是抄別人的,如果不太清楚,自行惡補)
remote service 實際上就是主程式包含服務模組,另外的一個程式可以調用。
由於delphi 10 的低級錯誤,需要手工修改一些東西。這一塊可以參考http://blog.qdac.cc/?p=2839
為了不影響這個例子的順利完成,本例中沒有使用上面的修改。直接在本例中處理。
現在開工:
和以前一樣,先建立一個遠程服務
組建檔案,儲存目錄。
開啟servicedmp
輸入以下代碼
uses Androidapi.Helpers;function TAndroidServiceDM.AndroidServiceHandleMessage(const Sender: TObject; const AMessage: JMessage): Boolean;const GET_STRING = 1234; SERVICE_STRING = 4321;var LMessage: JMessage; LBundle: JBundle;begin case AMessage.what of GET_STRING: begin LBundle := TJBundle.Create; // we can not send String because is not parcelable LMessage := TJMessage.Create; LMessage.what := SERVICE_STRING; LBundle.putString(TAndroidHelper.StringToJString(‘Key‘), TAndroidHelper.StringToJString(‘這是服務來的訊息!!!‘)); LMessage.obj := LBundle; AMessage.replyTo.send(LMessage); Result := True; end; else Result := False; end;end;
ok ,開始編譯,出現錯誤,當然了。EMB 同志犯了低級錯誤。
進入手動模式,開啟下面檔案:
修改
現在編譯,沒問題了,好,儲存。
現在我們建立一個新的工程,用來加入這個服務,並使用這個服務,介面如下:
注意擷取資料的按鈕的enabled:=False;
代碼如下
unit mainp;interfaceuses 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,System.Android.Service, Androidapi.JNI.Os;type TForm3 = class(TForm) Label1: TLabel; Button1: TButton; Button2: TButton; GetDataButton: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure GetDataButtonClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private FServiceConnection: TRemoteServiceConnection; procedure OnServiceConnected(const ServiceMessenger: JMessenger); procedure OnHandleMessage(const AMessage: JMessage); { Private declarations } public { Public declarations } end;var Form3: TForm3;const GET_STRING = 1234; SERVICE_STRING = 4321;implementation{$R *.fmx}uses AndroidApi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNI.Widget;procedure TForm3.Button1Click(Sender: TObject);begin // 綁定服務 FServiceConnection.BindService( // 包含服務的 APK 名稱 ‘com.embarcadero.xalionhostapp‘, // 服務名- 總是以 "com.embarcadero.services"開頭 ‘com.embarcadero.services.xalionremoteservice‘);end;procedure TForm3.Button2Click(Sender: TObject);begin // 取消綁定 if FServiceConnection <> nil then FServiceConnection.UnbindService; GetDataButton.Enabled := False;end;procedure TForm3.FormCreate(Sender: TObject);begin // 初始化服務串連 FServiceConnection := TRemoteServiceConnection.Create; FServiceConnection.OnConnected := OnServiceConnected; FServiceConnection.OnHandleMessage := OnHandleMessage;end;procedure TForm3.FormDestroy(Sender: TObject);begin FServiceConnection.Free;end;procedure TForm3.GetDataButtonClick(Sender: TObject);var LMessage: JMessage;begin LMessage := TJMessage.JavaClass.obtain(nil, GET_STRING); LMessage.replyTo := FServiceConnection.LocalMessenger; FServiceConnection.ServiceMessenger.send(LMessage);end;procedure TForm3.OnHandleMessage(const AMessage: JMessage);var LStr: JString; LBundle: JBundle;begin case AMessage.what of SERVICE_STRING: begin LBundle := TJBundle.Wrap(AMessage.obj); LStr := LBundle.getString(TAndroidHelper.StringToJString(‘Key‘)); TJToast.JavaClass.makeText(TAndroidHelper.Context, LStr.subSequence(0, LStr.length), TJToast.JavaClass.LENGTH_SHORT).show; end; else FServiceConnection.Handler.Super.handleMessage(AMessage); end;end;procedure TForm3.OnServiceConnected(const ServiceMessenger: JMessenger);begin GetDataButton.Enabled := True;end;end.
現在把剛才建立的服務加進去
編譯運行。
是不是可以正常運行了?
先點一下綁定服務,等擷取資料可以點時,點一下,就可以取到服務發來的訊息了。
OK,這隻是實現了內部的通訊,我們還需要另外做一個app. 讓它也可以使用這個服務。
重建立立一個新的APP.
介面如下:
代碼與主程式非常相似
unit mainp;interfaceuses 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,System.Android.Service, Androidapi.JNI.Os;type TForm3 = class(TForm) Label1: TLabel; Button1: TButton; Button2: TButton; GetDataButton: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure GetDataButtonClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private FServiceConnection: TRemoteServiceConnection; procedure OnServiceConnected(const ServiceMessenger: JMessenger); procedure OnHandleMessage(const AMessage: JMessage); { Private declarations } public { Public declarations } end;var Form3: TForm3;const GET_STRING = 1234; SERVICE_STRING = 4321;implementation{$R *.fmx}uses AndroidApi.Helpers, Androidapi.JNI.JavaTypes, Androidapi.JNI.Widget;procedure TForm3.Button1Click(Sender: TObject);begin // 綁定服務 FServiceConnection.BindService( // 包含服務的 APK 名稱 ‘com.embarcadero.xalionhostapp‘, // 服務名- 總是以 "com.embarcadero.services"開頭 ‘com.embarcadero.services.xalionremoteservice‘);end;procedure TForm3.Button2Click(Sender: TObject);begin // 取消綁定 if FServiceConnection <> nil then FServiceConnection.UnbindService; GetDataButton.Enabled := False;end;procedure TForm3.FormCreate(Sender: TObject);begin // 初始化服務串連 FServiceConnection := TRemoteServiceConnection.Create; FServiceConnection.OnConnected := OnServiceConnected; FServiceConnection.OnHandleMessage := OnHandleMessage;end;procedure TForm3.FormDestroy(Sender: TObject);begin FServiceConnection.Free;end;procedure TForm3.GetDataButtonClick(Sender: TObject);var LMessage: JMessage;begin LMessage := TJMessage.JavaClass.obtain(nil, GET_STRING); LMessage.replyTo := FServiceConnection.LocalMessenger; FServiceConnection.ServiceMessenger.send(LMessage);end;procedure TForm3.OnHandleMessage(const AMessage: JMessage);var LStr: JString; LBundle: JBundle;begin case AMessage.what of SERVICE_STRING: begin LBundle := TJBundle.Wrap(AMessage.obj); LStr := LBundle.getString(TAndroidHelper.StringToJString(‘Key‘)); TJToast.JavaClass.makeText(TAndroidHelper.Context, LStr.subSequence(0, LStr.length), TJToast.JavaClass.LENGTH_SHORT).show; end; else FServiceConnection.Handler.Super.handleMessage(AMessage); end;end;procedure TForm3.OnServiceConnected(const ServiceMessenger: JMessenger);begin GetDataButton.Enabled := True;end;end.
編譯,運行。
點綁定服務,奇怪了,怎麼擷取資料不出來,反而出現了“程式無反應” 是否關閉?
唉。又是 EMB 同志的低級錯誤。
手動模式,開啟主程式的目錄。
開啟這個檔案
把這個替換成
<service android:exported="true" android:name="com.embarcadero.services.xalionremoteservice" />
重新編譯運行主程式。
現在再運行擴充程式。怎麼樣,ok了?
delphi 10 seattle 安卓服務開發(三)