Delphi XE7 這個版本,表面上看跟 XE6 相比似乎改變不大,骨子裡筆者認為改進的幅度還是不小的,除了之前介紹到的 GCM、Splash Screen 等看得見的,還有 What's New 中提到的 New TMultiView Component、FireMonkey Save State Feature 等等...

不過筆者最關心的,其實是 What's New 中提到的另外一項「Add Java Libraries to Your Applications for Android」,在 Android 的世界就像是在 Windows 一樣,可以允許各式各樣的第三方廠商提供 SDK 來銜接周邊硬體,包含之前研討會中廖老師分享中提到的 IPCam、iBeacon、Bluetooth Printer 等等,廖老師在 FB 上分享的 powerpoint 也有稍微提到怎麼銜接,但是可能是時間關係,沒有細講,這部分就讓小弟來代勞一下吧...

截至筆者撰寫此文的同時,EMBT 尚未釋出 Java2OP.exe 這個工具的正式版本,照之前李維大師提供的訊息,目前已經進入 QA 階段,但釋出日期尚不得而知,因此在此時此刻若要先嘗試結合第三方廠商提供的 jar,必須先透過其他工具(需要 $$),比如 Java2PasJavaImport for Android 等等,.jar 的檔案就是 Java library file,其實就像 Windows 世界的 DLL,若要使用則必須知道其 API 的呼叫介面、參數等等,而上述工具就是把 .jar 轉成 .pas 的呼叫介面,方便 Delphi 的使用者來使用。

這次要舉的範例比較簡單,讓大家可以輕鬆入門,免得覺得這部分門檻太高,因此結合硬體的部分本次先跳過,畢竟這些周邊不是人人都有,這次要結合的是 Base64Coder in Java,這是一個 open source 的專案,主要提供 Base64 的 Encode 與 Decode,官方網站在此:http://www.source-code.biz/base64coder/java/ ,由於 android 在 API Level 8(Android 2.2)後才有內建 Base64 的 Encode 與 Decode 函式,因此若你的專案要向下相容更低版本的 android,勢必得自行準備這部分的 code,這時就可以引用這個 open source 寫好的東西。

首先我們要從上述網站取得 .jar,因此需要下載的是 full package

zip 檔案解壓縮後,可以在 target 這個目錄中找到 base64coder.jar 這個檔案,請先記住,等下會用到。

接下來就建立一個新的 app 專案,sample 畫面如下

兩個 TEdit、兩個 TButton、兩個 TText 與兩個 TLabel

接下來透過轉換工具,把 .jar 轉換成 .pas,可以得到一個檔案 biz.source_code.base64Coder.Base64Coder.pas

由於大家目前可能沒有工具可用,因此我把 biz.source_code.base64Coder.Base64Coder.pas 先貼在這裡,等到大家可以取得 EMBT 官方的工具 Java2OP.exe,就可以自行產生這個檔案了

unit biz.source_code.base64Coder.Base64Coder;

interface

uses
  AndroidAPI.JNIBridge,
  Androidapi.JNI.JavaTypes;

type
  JBase64Coder = interface;

  JBase64CoderClass = interface(JObjectClass)
    ['{53EF8745-17D8-455E-82D9-7075C3735DA0}']
    function decode(JStringparam0 : JString) : TJavaArray<Byte>; cdecl; overload;// (Ljava/lang/String;)[B A: $9
    function decode(TJavaArrayCharparam0 : TJavaArray<Char>) : TJavaArray<Byte>; cdecl; overload;// ([C)[B A: $9
    function decode(TJavaArrayCharparam0 : TJavaArray<Char>; Integerparam1 : Integer; Integerparam2 : Integer) : TJavaArray<Byte>; cdecl; overload;// ([CII)[B A: $9
    function decodeLines(JStringparam0 : JString) : TJavaArray<Byte>; cdecl;    // (Ljava/lang/String;)[B A: $9
    function decodeString(JStringparam0 : JString) : JString; cdecl;            // (Ljava/lang/String;)Ljava/lang/String; A: $9
    function encode(TJavaArrayByteparam0 : TJavaArray<Byte>) : TJavaArray<Char>; cdecl; overload;// ([B)[C A: $9
    function encode(TJavaArrayByteparam0 : TJavaArray<Byte>; Integerparam1 : Integer) : TJavaArray<Char>; cdecl; overload;// ([BI)[C A: $9
    function encode(TJavaArrayByteparam0 : TJavaArray<Byte>; Integerparam1 : Integer; Integerparam2 : Integer) : TJavaArray<Char>; cdecl; overload;// ([BII)[C A: $9
    function encodeLines(TJavaArrayByteparam0 : TJavaArray<Byte>) : JString; cdecl; overload;// ([B)Ljava/lang/String; A: $9
    function encodeLines(TJavaArrayByteparam0 : TJavaArray<Byte>; Integerparam1 : Integer; Integerparam2 : Integer; Integerparam3 : Integer; JStringparam4 : JString) : JString; cdecl; overload;// ([BIIILjava/lang/String;)Ljava/lang/String; A: $9
    function encodeString(JStringparam0 : JString) : JString; cdecl;            // (Ljava/lang/String;)Ljava/lang/String; A: $9
  end;

  [JavaSignature('biz/source_code/base64Coder/Base64Coder')]
  JBase64Coder = interface(JObject)
    ['{3448CA5F-F6E7-4013-A4A1-F5CFD4161D0C}']
  end;

  TJBase64Coder = class(TJavaGenericImport<JBase64CoderClass, JBase64Coder>)
  end;

implementation

end.

把上述 .pas 引用到 app 專案中,兩個  button 個別去呼叫 encodeString 與 decodeString,程式碼如下

unit uBase64Jar;

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.Edit, FMX.Objects;

type
  TForm1 = class(TForm)
    edtEncode: TEdit;
    btnEncode: TButton;
    edtDecode: TEdit;
    btnDecode: TButton;
    Label1: TLabel;
    txtEncode: TText;
    Label2: TLabel;
    txtDecode: TText;
    procedure btnEncodeClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnDecodeClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID}

uses
  biz.source_code.base64Coder.Base64Coder, Androidapi.Helpers;

procedure TForm1.btnDecodeClick(Sender: TObject);
begin
  txtDecode.Text :=
    JStringToString(TJBase64Coder.JavaClass.decodeString(StringToJSTring(edtDecode.Text)));
end;

procedure TForm1.btnEncodeClick(Sender: TObject);
begin
  txtEncode.Text :=
    JStringToString(TJBase64Coder.JavaClass.encodeString(StringToJSTring(edtEncode.Text)));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  edtEncode.Text := '';
  txtEncode.Text := '';
  edtDecode.Text := '';
  txtDecode.Text := '';
end;

end.

在編譯之前,請先開啟 Project Manager,並且把 .jar 檔案加到 Library 目錄中

然後開啟 Deployment,確認取消勾選原本 EMBT 內附的 classes.dex

執行看看吧

太完美了,不需要再自行編譯 classes.dex,XE7 代勞...

比賽結束...

    縹緲 發表在 痞客邦 留言(4) 人氣()