Delphi XE10 在推出了一份代码, 编译后到Android, iOS, windows等环境下后, 从来没接触过Delphi的我, 被赶鸭子上架来做Delphi的开发.
尝试在Delphi XE10中引用第三方Jar包时, 遇到了一些问题, 折腾了2天多才解决, 现总结到这里..
重点(敲黑板):
使用第三方Jar包的过程其实挺简单, 但是一直遇到"Java class XXX Could not be found"的错误:
这是因为虽然在Delphi工程中包含了第三方Jar包, 但是打成apk包的时候, 并没有把第三方Jar包的内容打入APK包中, 下面是示例调用Sample.jar, 可以看到Sample.Jar中的文件, 并没有被打入包中:
正确的打包后, apk中的结构应该是如下的:
目前没有找到这个问题的具体原因, 怀疑是跟Delphi XE 10编译环境有关.
目前的解决方法: 卸载XE10, 然后重装, 重新建立新工程, 发现问题消失...
下面是完整步骤
1. 到百度定位SDK的网站上, 注册并下载百度定位SDK:
2. 使用老猫的JarOrClass2Pas工具, 将百度定位SDK的jar文件, 转换成Pas文件...工具自行百度查找
JarOrClass2Pas_FlyingWang
3. 将转换后的Pas文件以及其他的百度定位SDK文件放在一起(例如BaiduLBS文件夹中), 拷贝到Delphi工程目录:
5. 在Delphi工程中, 加入Androidapi.JNI.BaiduLBS_Android.pas, 并将BaiduLBS_Android.jar 添加到工程中:
4. 在Delphi代码中引入, 完整的示例代码如下:
- unit Unit3;
-
- interface
-
- uses
- System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
- FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
- FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
-
- Androidapi.JNI.JavaTypes,
- Androidapi.JNIBridge,
- AndroidApi.JNI.GraphicsContentViewText,
- {$IF CompilerVersion >= 27.0} // >= XE6
- Androidapi.Helpers,
- {$ENDIF}
- {$IF CompilerVersion < 28.0} // < XE7
- FMX.Helpers.Android,
- {$ENDIF}
- Androidapi.JNI.BaiduLBS_Android;
-
- type
- TForm3 = class(TForm)
- btnBaidu: TButton;
- memoOutput: TMemo;
- procedure btnBaiduClick(Sender: TObject);
- private
- BDLocationListener: JBDLocationListener;
- public
- { Public declarations }
- end;
-
- MyLocationListener = class(TJavaLocal, JBDLocationListener)
- public
- function equals(o: JObject): boolean; cdecl;
- function getClass: Jlang_Class; cdecl;
- function hashCode: integer; cdecl;
- procedure notify; cdecl;
- procedure notifyAll; cdecl;
- function toString: JString; cdecl;
- procedure wait; overload; cdecl;
- procedure wait(millis: Int64); overload; cdecl;
- procedure wait(millis: Int64; nanos: integer); overload; cdecl;
- procedure onReceiveLocation(P1: JBDLocation); cdecl;
- procedure onConnectHotSpotMessage(P1: JString; P2: Integer); cdecl;
- end;
-
- var
- Form3: TForm3;
-
- implementation
-
- {$R *.fmx}
-
- function MyLocationListener.equals(o: JObject): boolean;
- begin
-
- end;
-
- function MyLocationListener.getClass: Jlang_Class;
- begin
-
- end;
-
- function MyLocationListener.hashCode: integer;
- begin
-
- end;
-
- procedure MyLocationListener.notify;
- begin
-
- end;
-
- procedure MyLocationListener.notifyAll;
- begin
-
- end;
-
- procedure MyLocationListener.onReceiveLocation(P1: JBDLocation);
- begin
- Form3.memoOutput.Lines.Add('recv: ' + P1.getLongitude().ToString() + ', '
- + P1.getLatitude().ToString());
- end;
-
- procedure MyLocationListener.onConnectHotSpotMessage(P1: JString; P2: Integer);
- begin
-
- end;
-
- function MyLocationListener.toString: JString;
- begin
-
- end;
-
- procedure MyLocationListener.wait;
- begin
-
- end;
-
- procedure MyLocationListener.wait(millis: Int64);
- begin
-
- end;
-
- procedure MyLocationListener.wait(millis: Int64; nanos: integer);
- begin
-
- end;
-
- procedure TForm3.btnBaiduClick(Sender: TObject);
- var
- jlc : JLocationClient;
- locaOpt: JLocationClientOption;
- begin
- try
- locaOpt := TJLocationClientOption.JavaClass.init();
- locaOpt.setCoorType(StringToJString('bd09ll'));
- locaOpt.setScanSpan(5000);
- jlc := TJLocationClient.JavaClass.init(TAndroidHelper.Context, locaOpt);
- BDLocationListener := MyLocationListener.Create;
- jlc.registerLocationListener(BDLocationListener);
- jlc.start();
- except on E:Exception do
- Self.memoOutput.Lines.Add(E.Message);
- end;
- end;
- end.
5. 在Project -> Deployment中, 添加百度地图依赖的so文件:
6. 根据百度定位SDK的使用说明, 以及该android的信息, 在百度定位SDK中, 注册自己的app, 获取到API_KEY
7. 将API_KEY按照AndroidManifest.xml 中的样子, 写入到Delphi项目的AndroidManifest.template.xml文件中:
8. 以示例代码为例, 点击按钮就可以进行定位了: