delphi 10 seattle 安卓服务开发(三)

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;

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,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;

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,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了?

时间: 2024-10-13 11:36:57

delphi 10 seattle 安卓服务开发(三)的相关文章

delphi 10 seattle 安卓服务开发(一)

从delphi 开始支持安卓的开发开始, 安卓service 开发一直都是delphier 绕不过去的坎, 以前也有开发service  的方法,但是都是手工处理启动文件,而且要修改很多东西,基本上成功 的概率很低. delphi 10 seattle(这个名字很特殊,与win10 一样,直接跳过了9) 终于官方支持安卓service 开发了, 不知道现在现在开发安卓service 是不是很简单?那么就让我们一探究竟. 首先,我们开启已经扁平的不能再扁平delphi 10, 选择建立一个其他项目

delphi 10 seattle 安卓服务开发(二)

关于delphi 10 移动服务开发的几张图

Delphi 10.1.2 berlin开发跨平台APP的几点经验

1.ios不允许app有退出功能,所以不能调用Application.Terminate. 2.info.plist文件的自定义:info.plist文件是由info.plist.TemplateiOS.xml生成的,如果需要定制info.plist内容,则修改info.plist.TemplateiOS.xml即可 3.界面文字的大小建议使用13,统一android与ios的显示,我在android下用12,生成ios app时,发现小些. 4.使用TFrame来做界面,感觉效率比Form要好

Delphi 10 Seattle 发布到 iOS 6~8 闪退问题之解决方案

问题一:iOS 9 于 2015/09/16 开放下载了,但之前使用 Delphi 开发上架的 App 皆会闪退,无法运行在 iOS 9. 问题二:使用 Delphi 10 Seattle + Xcode 7.0 + iOS SDK 9.0 发布到 iOS 9 的真机没有问题,但发布到 iOS 6~8 的机子会闪退. 为了解决以上问题,可以参考下列方法(仅供参考,希望 EMB 能尽快提供 Delphi 10 Seattle 的 Hot Fix): 开发环境: 换回 Delphi XE8 upda

Delphi 10 Seattle Update 1 修复 iOS HTTP 协定需求

在 iOS 9 Apple 加入了 HTTP 协议,还好有 TMS 提供快速修复工具,得以能顺利上架到 App Store. 现在 Delphi 10 Seattle Update 1 提供了这个设定功能,无需再使用 TMS 修复工具了,见下图:

delphi 10 seattle 中 解决IOS 9 限制使用HTTP 服务问题

IOS 9 于17号早上正式开始推送,早上起来立马安装,这次升级包只有1G, 安装空间也大大降低(想起IOS 8 升级时,几乎把手机里面的东西删光了,满眼都是泪). 虽然安装后,网上几乎是铺天盖地的吐槽,但是如果不安装的话,拿什么吐呢?:) 回到正题,既然IOS 9出来了,那么前几天刚出来的delphi 10 会怎么想?是支持呢,还是不支持? 昨天晚上把所有的准备条件搞好(xcode7+ios 9 SDK). 把以前的几个程序重新编译发布,基本上没有问题,可以正常运行.以为大事已定.突然发现 原

Delphi 10 Seattle plus 新特性——System.JSON.Builders

1 { 2 全能中间件 -- 简单.高效.稳定.安全的三层中间件 3 4 1.支持 多账套多数据库,包括SQLite, MySQL, SQL Server, Oracle, PostgreSQL, DB2, SQL Anywhere,Firebird等多种数据库. 5 2.支持 快速开发,封装了 TRFConnection 和 TRFDataSet 控件供客户端使用,传统两层应用轻松升级为三层应用. 6 3.支持 数据压缩.加密传输,效率和安全有保障. 7 4.支持 数据连接池,提高并发响应速度

Delphi 10.1 Berlin 与 Delphi 10 Seattle 共存

以下安装环境是win7 64位 1. 安装Delphi10.1 Berlin 版本. 2.修改C:\Program Files (x86)\Embarcadero\Studio\18.0\cglm.ini文件 [Embarcadero License Management]RootDir=${MODULE_DIR}\..LicenseDir=${ROOTDIR}\LicenseInfoDir=${COMMON_APPDATA}\Embarcadero\18\.licensesSlipDir=${

DELPHI 10 SEATTLE 在OSX上安装PASERVER

旧版本的DELPHI在安装目录下里的PASERVER目录有安装文件,但奇怪在这个SEATTLE上的PASERVER目录下只有一个EXE程序的安装程序??,显然不能安装到OSX里,需要在Embarcadero官网上找到下载页面手动下载后拷贝到OSX里安装,?http://docwiki.embarcadero.com/RADStudio/Seattle/en/Installing_the_PAServer_Manager_on_a_Mac??