Delphi XE10 使用百度定位SDK Jar包進行定位
Delphi XE10 在推出了一份代碼, 編譯後到Android, iOS, windows等環境下後, 從來沒接觸過Delphi的我, 被趕鴨子上架來做Delphi的開發.
嘗試在Delphi XE10中引用第三方Jar包時, 遇到了一些問題, 折騰了2天多才解決, 現總結到這裡..
重點(敲黑闆):
使用第三方Jar包的過程其實挺簡單, 但是一直遇到"Java class XXX Could not be found"的錯誤:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZD9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwlco5WW040MjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DOxYTMzEzM5ATMwQDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
這是因為雖然在Delphi工程中包含了第三方Jar包, 但是打成apk包的時候, 并沒有把第三方Jar包的内容打入APK包中, 下面是示例調用Sample.jar, 可以看到Sample.Jar中的檔案, 并沒有被打入包中:
正确的打包後, apk中的結構應該是如下的:
目前沒有找到這個問題的具體原因, 懷疑是跟Delphi XE 10編譯環境有關. 目前的解決方法: 解除安裝XE10, 然後重裝, 重建立立新工程, 發現問題消失...
下面是完整步驟
1. 到百度定位SDK的網站上, 注冊并下載下傳百度定位SDK: http://lbsyun.baidu.com/
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. 以示例代碼為例, 點選按鈕就可以進行定位了:
如果出現閃退, 請參考 點選打開連結
完整示例代碼的路徑: 點選打開連結