Nokia 官方提供的 JSR-179 參考實作 TouristRoute**,展示完整 LBS 應用架構:從定位服務搜尋、位置更新顯示、地標編輯/儲存、指南針/俯仰翻滾顯示,到接近警示。原始碼可從 Nokia Forum 下載。注意:Series 40 平台無法正常執行** (缺乏 GPS 硬體與 JSR-179 實作),需在 S60 3rd Edition FP1+ 裝置或模擬器測試。
| 類別 | 對應畫面 | 核心功能 |
|---|---|---|
TouristUI | 主畫面 (Route View) | 顯示當前經緯度、速度、距離、地址、地標清單 |
LandmarkEditorUI | 地標編輯器 | 列舉/新增/刪除地標、輸入名稱/描述/地址欄位 |
CompassUI | 指南針 | 繪製方位角刻度、指標、數值顯示 (需 Orientation 支援) |
PitchRollUI | 俯仰/翻滾 | 3D 感測器裝置顯示 Pitch/Roll 角度動畫 |
啟動 → 搜尋 Provider → [找到] → Route View (TouristUI)
│
┌───────────────┼───────────────┐
▼ ▼ ▼
[Edit 指令] [Compass 指令] [Landmarks 指令]
│ │ │
▼ ▼ ▼
LandmarkEditorUI CompassUI Landmark List
│ │
▼ ▼
[Save/Delete] [Pitch/Roll 指令]
│
▼
PitchRollUI
locationUpdated 事件到達前,顯示「正在尋找定位服務…」等待畫面 (MessageUI)。firstLocationUpdateEvent() → 建立 TouristUI 並 display.setCurrent() 進入主畫面。TouristData (Model) 參考,透過 ProviderStatusListener 回報 Provider 狀態變更。| 類別 | 職責 | 關鍵介面/協作 |
|---|---|---|
ConfigurationProvider | 單例,封裝 Criteria 陣列、自動搜尋 Provider、Orientation 初始化 | ProviderStatusListener, ProviderSelectedListener |
TouristData | 實作 LocationListener/ProximityListener,處理位置更新與接近事件,轉發給 UI | 持有 TouristUI, CompassUI, LandmarkEditorUI 弱參考 |
ControlPoints | 地標存儲管理:LandmarkStore CRUD、分類、區域查詢 | 單例,供 LandmarkEditorUI 呼叫 |
ProviderStatusListener | 介面:providerSelectedEvent(), firstLocationUpdateEvent(), providerStateChanged() | TouristMIDlet 實作 |
// TouristMIDlet.startApp()
protected void startApp() {
display = Display.getDisplay(this);
if (ConfigurationProvider.isLocationApiSupported()) {
ConfigurationProvider.getInstance().autoSearch(this); // 非同步搜尋
} else {
MessageUI.showApiNotSupported();
}
}
// ConfigurationProvider.autoSearch() 找到 Provider 後:
listener.providerSelectedEvent(); // 在 TouristMIDlet 執行
// TouristMIDlet.providerSelectedEvent()
public void providerSelectedEvent() {
synchronized (mutex) { // 確保 TouristData 只建立一次
MessageUI.showLocationProviderState(); // 顯示「正在取得位置資料…」
data = new TouristData(this); // 建立 Model,內部註冊 LocationListener
}
}
// TouristData 收到首次 locationUpdated → 回呼 TouristMIDlet.firstLocationUpdateEvent()
public void firstLocationUpdateEvent() {
synchronized (mutex) { // 等待 providerSelectedEvent 完成
TouristUI ui = new TouristUI(data);
data.setTouristUI(ui);
display.setCurrent(ui); // 真正進入主畫面
}
}
設計亮點:mutex 確保 TouristData 建立與 UI 顯示的原子性,避免競態條件導致 NullPointerException 或重複建立 UI。
com.nokia.example.location.tourist
├── TouristMIDlet.java // MIDlet 進入點、生命週期、ProviderStatusListener 實作
├── model
│ ├── ConfigurationProvider.java // Provider 搜尋、Criteria 管理、Orientation 存取
│ ├── TouristData.java // LocationListener/ProximityListener、資料分發
│ ├── ControlPoints.java // LandmarkStore 管理
│ ├── ProviderStatusListener.java // 介面
│ └── ProviderSelectedListener.java // 介面
├── ui
│ ├── TouristUI.java // 主畫面
│ ├── LandmarkEditorUI.java // 地標編輯
│ ├── CompassUI.java // 指南針
│ ├── PitchRollUI.java // 俯仰/翻滾
│ ├── ProviderQueryUI.java // 詢問付費 Provider 對話框
│ └── MessageUI.java // 等待/錯誤訊息
└── util
└── Utils.java // formatDouble() 等工具方法
https://code.yunyiwangluo.com/bianchen/UploadFiles_4619/201701/2017011209312041.jpghttps://code.yunyiwangluo.com/bianchen/UploadFiles_4619/201701/2017011209312122.jpghttps://code.yunyiwangluo.com/bianchen/UploadFiles_4619/201701/2017011209312159.jpghttps://code.yunyiwangluo.com/bianchen/UploadFiles_4619/201701/2017011209312105.jpg下一篇將深入 ConfigurationProvider 靜態 Criteria 建構、TouristData 事件處理執行緒模型、ControlPoints 地標存儲實作細節,以及 Utils.formatDouble() 格式化工具。