Delphi 長期以來作為 Windows 桌面開發的利器,如今也提供強大的跨平台能力。FireMonkey 框架讓開發者能以單一程式碼函式庫,建構原生 Windows、macOS 和 Linux 應用程式。本文除了說明如何在不同平台上編譯和佈署 Delphi 應用程式外,更著重於 App Tethering 技術的應用,讓桌面應用程式能與行動裝置無縫互動。此技術能簡化跨裝置通訊的複雜度,讓開發者輕鬆實作資料交換和控制,例如本文中示範的照片傳輸功能,便展現了 App Tethering 的實用性與便利性,有助於提升應用程式的跨平台整合能力。
跨平台桌面應用程式開發與行動橋接技術
在現代軟體開發中,跨平台應用程式的開發已成為主流趨勢。Delphi作為一個強大的開發工具,提供了對多個桌面平台的原生支援,包括Windows、macOS和Linux。本章節將探討如何使用Delphi和FireMonkey開發跨平台桌面應用程式,並介紹如何利用App Tethering技術實作桌面與行動裝置之間的通訊。
為macOS建立應用程式
Apple的macOS是僅次於Windows的第二大桌面平台。近年來,macOS經歷了重大變革,捨棄了Intel CPU而轉向ARM CPU。雖然使用Delphi編譯的Intel應用程式可以透過Rosetta模擬層在新的ARM CPU上執行,但仍強烈建議將應用程式遷移到新的ARM目標平台。值得注意的是,ARM二進位制檔無法在Intel Mac上執行。
Delphi支援為macOS建立原生ARM和原生Intel應用程式(見圖9.17),並且能夠將它們合併成單一的二進位制檔(稱為通用二進位制檔)以供商店分發。兩個macOS目標平台都是64位平台,因為Apple已經終止了對其所有作業系統上32位應用程式的支援。
將DropTarget演示專案移植到macOS
我們可以重新為macOS編譯DropTarget演示專案,並利用相同的功能。不過,首先我們要在演示專案中新增一個小功能,以展示FireMonkey針對macOS的特定功能:
- 重新開啟DropTarget演示專案,並新增一個
TMainMenu元件。組態選單,新增一個簡單的「幫助」選單和一個「關於」專案,如圖9.18所示。 - 為「關於」選單專案新增事件處理程式,使用
ShowMessage呼叫顯示資訊訊息。
在Windows上執行程式時,您會看到一個常規選單新增到表單中,位於標題列下方。在Mac上執行程式時,您會看到螢幕頂部出現了一個平台選單,如圖9.19所示。
這是一個很好的例子,展示了FireMonkey應用程式如何適應不同目標平台的特定UI需求。
針對Linux的開發
Delphi的企業版包含了一個針對Linux Intel 64位平台的原生編譯器。雖然FireMonkey本身不支援Linux,但Embarcadero授權並分發了FMXLinux附加元件,一個將FireMonkey的所有功能帶到Linux的函式庫。這個函式庫可以在Delphi IDE的GetIt套件管理器中找到。只需開啟GetIt(從工具選單或歡迎頁面),搜尋Linux,就會看到該套件,可以輕鬆安裝,如圖9.20所示。
組態Linux開發環境
在建立FMXLinux應用程式之前,需要為Windows目標組態建立應用程式。第一步是使用適當的工具組態Linux電腦。有詳細步驟可參考https://docwiki.embarcadero.com/RADStudio/en/Linux_Application_Development。
完成上述步驟後,您可以在Delphi IDE組態中新增Linux SDK,類別似於其他平台的操作。
在Linux上執行應用程式
組態好Linux平台並安裝FMXLinux後,您可以在Linux機器上啟動PAServer,建立應用程式,並直接佈署。UI將在Linux機器上執行。如圖9.21所示,它展示了一個非常特定的組態,在Windows子系統Linux(WLS 2.0)上執行Ubuntu。在這種情況下,應用程式可以與Windows應用程式無縫使用,因為Windows Linux子系統將其託管在Windows框架中。
App Tethering技術
App Tethering是Delphi的一個獨特功能,可用於在不同型別的應用程式之間建立通訊,例如在任何支援的平台上使用FireMonkey執行的行動或桌面應用程式。它也可以用於Windows特定的VCL函式庫。App Tethering最初的使用案例是能夠將現有的桌面應用程式擴充套件到行動裝置,並輕鬆建立行動配套應用程式。
使用App Tethering的基本步驟
- 在需要通訊的兩個應用程式中,各自放置兩個App Tethering元件:
TTetheringManager和TTetheringAppProfile。 TTetheringAppProfile元件具有Manager屬性,用於連線相關聯的TTetheringManager。- App Tethering可以使用Wi-Fi或藍牙進行通訊。
TTetheringManager元件具有AllowedAdapters屬性,可以指定要使用的通訊協定。
發起通訊
通訊由發現其他可用的Tethering管理器開始。作為客戶端的應用程式需要呼叫TTetheringManager元件上的DiscoverManagers方法。當發現程式完成後,將觸發OnEndDiscovery事件,並將發現的管理器列表傳遞給該事件的ARemoteManagers引數,型別為TTetheringManagerInfoList。
// 範例程式碼:設定TTetheringManager
TetheringManager1.AllowedAdapters := 'Network';
// 發起發現
TetheringManager1.DiscoverManagers();
// 事件處理程式:OnEndDiscovery
procedure TForm1.TetheringManager1EndDiscovery(const Sender: TObject; const ARemoteManagers: TTetheringManagerInfoList);
begin
// 處理發現的管理器列表
end;
內容解密:
上述範例展示瞭如何設定TTetheringManager以使用網路作為通訊協定,並發起對其他Tethering管理器的發現。當發現過程完成時,OnEndDiscovery事件被觸發,您可以在此事件處理程式中處理發現的管理器列表。這是實作App Tethering的第一步,使您的應用程式能夠與其他使用相同技術的應用程式進行通訊。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Delphi跨平台桌面與行動應用程式開發
package "Linux Shell 操作" {
package "檔案操作" {
component [ls/cd/pwd] as nav
component [cp/mv/rm] as file
component [chmod/chown] as perm
}
package "文字處理" {
component [grep] as grep
component [sed] as sed
component [awk] as awk
component [cut/sort/uniq] as text
}
package "系統管理" {
component [ps/top/htop] as process
component [systemctl] as service
component [cron] as cron
}
package "管線與重導向" {
component [| 管線] as pipe
component [> >> 輸出] as redirect
component [$() 命令替換] as subst
}
}
nav --> file : 檔案管理
file --> perm : 權限設定
grep --> sed : 過濾處理
sed --> awk : 欄位處理
pipe --> redirect : 串接命令
process --> service : 服務管理
note right of pipe
命令1 | 命令2
前者輸出作為後者輸入
end note
@enduml
圖表翻譯:
此圖表展示了使用App Tethering進行通訊的基本流程。首先啟動App Tethering,接著設定TTetheringManager元件,然後發起對其他可用Tethering管理器的搜尋。當搜尋完成後,將觸發OnEndDiscovery事件,最終與遠端管理器建立連線。這一系列步驟使應用程式能夠跨裝置進行有效的資料交換和控制。
應用程式繫結技術(App Tethering)實作詳解
應用程式繫結技術(App Tethering)是Embarcadero Delphi提供的一種強大的技術,能夠讓不同裝置上的應用程式透過網路進行通訊和資料交換,無需複雜的網路設定。本文將詳細介紹如何使用App Tethering實作一個簡單的系統,其中包括一個行動裝置應用程式用於拍攝照片並傳送到桌面應用程式進行顯示。
實作步驟
首先,我們需要建立一個Delphi多裝置空白應用程式,並儲存主表單為uFormPhotoTake,整個專案命名為PhotoTake。然後,變更表單的Name屬性為FormPhotoTake。
建立使用者介面
- 在表單上放置一個
TToolbar元件,並在其上新增一個TSpeedButton,將其Name屬性設為SpdbtnSendPhoto,並將其對齊方式設為Right。 - 再新增一個
TSpeedButton,對齊到Bottom,並將其Name屬性設為SpdbtnTakePhoto。 - 放置一個
TImage元件在表單上,對齊到Client,並將其Name屬性設為ImagePhoto。
設定動作列表
- 在表單上放置一個
TActionList元件,雙擊它並新增一個TakePhotoFromCameraAction動作,將其CustomText屬性設為「Take Photo」。 - 雙擊該動作的
OnDidFinishTaking事件,輸入以下程式碼以在表單上的影像元件中顯示從相機拍攝的照片:
procedure TFormPhotoTake.TakePhotoFromCameraAction1DidFinishTaking(Image: TBitmap);
begin
ImagePhoto.Bitmap.Assign(Image);
end;
- 將
SpdbtnTakePhoto按鈕的Action屬性連線到TakePhotoFromCameraAction1動作。
設定 App Tethering 元件
- 在表單上放置
TTetheringManager和TTetheringAppProfile元件,將它們的名稱分別設為TetherMng1和TetherProf1。將TetherProf1的Manager屬性設為TetherMng1。 - 為了避免連線到網路上隨機的可見應用程式,我們需要為兩個應用程式設定相同的密碼。在
TetherMng1的Password屬性中輸入一個任意的密碼。
實作傳送照片功能
- 新增一個動作到動作列表,將其名稱設為
ActSendPhoto,並將其連線到SpdbtnSendPhoto按鈕。實作其OnExecute事件以啟動 App Tethering 程式:
procedure TFormPhotoTake.ActSendPhotoExecute(Sender: TObject);
begin
if not ImagePhoto.Bitmap.IsEmpty then
TetherMng1.DiscoverManagers(1000)
else
ShowMessage('請先拍攝照片');
end;
發現遠端管理器和連線
- 當遠端管理器被發現時,會執行
OnEndManagersDiscovery事件。在這個事件處理函式中,我們與列表中的第一個管理器配對:
procedure TFormPhotoTake.TetherMng1EndManagersDiscovery(const Sender: TObject; const ARemoteManagers: TTetheringManagerInfoList);
begin
if ARemoteManagers.Count > 0 then
TetherMng1.PairManager(ARemoteManagers[0])
else
ShowMessage('找不到任何接收照片的應用程式');
end;
- 配對完成後,會執行
OnEndProfilesDiscovery事件。在這個事件處理函式中,我們連線到列表中的第一個遠端組態檔,並傳送影像:
procedure TFormPhotoTake.TetherMng1EndProfilesDiscovery(const Sender: TObject; const ARemoteProfiles: TTetheringProfileInfoList);
var
Memstr: TMemoryStream;
begin
if ARemoteProfiles.Count > 0 then
begin
if not TetherProf1.Connect(ARemoteProfiles[0]) then
ShowMessage('連線到遠端組態檔失敗')
else
begin
Memstr := TMemoryStream.Create;
try
ImagePhoto.Bitmap.SaveToStream(Memstr);
if TetherProf1.SendStream(ARemoteProfiles[0], 'Photo', Memstr) then
ShowMessage('影像已傳送')
else
ShowMessage('傳送影像失敗');
finally
Memstr.Free;
end;
end;
end
else
ShowMessage('找不到任何可連線的遠端組態檔');
end;
程式碼解析
TFormPhotoTake.ActSendPhotoExecute
此段程式碼檢查是否已拍攝照片,如果有,則呼叫 TetherMng1.DiscoverManagers(1000) 開始發現遠端管理器的過程。
TFormPhotoTake.TetherMng1EndManagersDiscovery
此事件處理函式在發現遠端管理器後被呼叫。它嘗試與第一個發現的遠端管理器配對。
TFormPhotoTake.TetherMng1EndProfilesDiscovery
此事件處理函式在配對成功後被呼叫。它連線到第一個可用的遠端組態檔,並透過 SendStream 方法傳送影像。
使用應用程式繫結(App Tethering)實作跨裝置照片傳輸
在上一章節中,我們學習瞭如何使用Delphi開發行動應用程式。在本章節中,我們將探討桌面應用程式的開發,並介紹如何使用應用程式繫結技術實作跨裝置的資料交換。
建立照片接收應用程式
要實作跨裝置的照片傳輸,我們需要建立兩個應用程式:一個用於拍攝和傳送照片,另一個用於接收和顯示照片。接收照片的應用程式比傳送照片的應用程式更簡單,因為它只需要監聽通訊請求並接收傳送的資訊。
步驟1:建立新專案
首先,在現有的專案群組中新增一個新的多裝置空白Delphi應用程式,並將主表單單元儲存為uFormPhotoDisplay,將專案儲存為PhotoDisplay。
步驟2:設計使用者介面
- 在表單上放置一個
TToolbar元件和一個TLabel元件,將標籤的HorzAlign屬性設定為Center,並在Text屬性中輸入「Photo Display」。 - 在表單上放置一個
TImage元件,將其對齊方式設定為Client,並重新命名為ImageDisplay。
步驟3:新增應用程式繫結元件
- 在表單上放置一個
TTetheringManager元件和一個TTetheringAppProfile元件,分別命名為TetherMng1和TetherProf1。 - 將
TetherProf1的Manager屬性設定為TetherMng1,以連線兩個元件。
步驟4:設定密碼和處理事件
- 在
TetherMng1的Password屬性中輸入與拍攝照片應用程式相同的密碼。 - 在
OnRequestManagerPassword事件中傳遞密碼給元件。 - 處理
TetheringAppProfile1的OnResourceReceived事件,以接收和載入傳送的照片。
procedure TFormPhotoDisplay.TetherProf1ResourceReceived(
const Sender: TObject; const AResource: TRemoteResource);
begin
ImageDisplay.Bitmap.LoadFromStream(AResource.Value.AsStream);
end;
測試和佈署
在佈署到行動裝置之前,可以先在Windows上測試兩個應用程式。雖然Windows上通常沒有相機,但可以在設計時將測試圖片載入到ImagePhoto中,以測試實際的傳送功能。
嵌入式資料函式庫
大多數行動應用程式都需要處理資料。建立資料函式庫應用程式一直是Delphi的最大優勢之一。在本章節中,我們將學習如何在FireMonkey中建立資料驅動的行動使用者介面,如何使用FireDAC資料庫存取框架,以及如何在行動裝置上嵌入資料函式庫。
技術需求
資料驅動應用程式
要建立資料驅動的應用程式,我們需要了解如何使用FireDAC存取資料函式庫,以及如何建立資料驅動的使用者介面。
選擇資料函式庫
在選擇資料函式庫時,我們需要考慮行動裝置的效能和儲存空間限制。常見的選擇包括SQLite和其他輕量級資料函式庫。
使用FireDAC存取資料函式庫
FireDAC是一個強大的資料庫存取框架,可以讓我們輕鬆地存取各種資料函式庫。我們可以使用FireDAC的元件來連線資料函式庫,並執行查詢和更新操作。
建立資料驅動的使用者介面
要建立資料驅動的使用者介面,我們需要使用LiveBindings技術,將資料函式庫中的資料繫結到使用者介面元件上。這樣,當資料函式庫中的資料變更時,使用者介面會自動更新。
使用視覺化LiveBindings
LiveBindings是一種強大的技術,可以讓我們將資料函式庫中的資料繫結到使用者介面元件上,而不需要編寫任何程式碼。我們可以使用視覺化LiveBindings設計工具來建立資料繫結。
快速使用者介面原型設計
使用LiveBindings和FireDAC,我們可以快速建立資料驅動的使用者介面原型,並進行測試和除錯。