用 Windows。Devices.Geolocation API 用於偵測裝置在 Windows 應用程式 SDK(WinUI 3)應用程式中的地理位置。 你可以取得一次性位置資訊,或隨時間持續追蹤使用者的位置。 本文涵蓋權限處理、一次性及連續位置讀取,以及如何在位置變更時更新使用者介面。
附註
這些 Windows.Devices.Geolocation API 是 Windows 執行階段(WinRT)API,適用於 UWP 和 WinUI 3 桌面應用程式。 本文中的程式碼使用了 WinUI 3 模式(例如使用 DispatcherQueue 進行執行緒封送處理)。
先決條件
- 這是一個由 Blank App, Packaged(桌面版 WinUI 3) 範本建立的 WinUI 3 專案。
- 在套件資訊清單中宣告的 定位 功能(請參閱 啟用定位功能)。
啟用位置功能
你的應用程式必須先宣告 位置 功能,才能存取使用者的位置。
- 在 方案總管 中,雙擊 Package.appxmanifest,然後選擇「能力」標籤。
- 勾選 地點方框。
這在清單中新增了以下條目:
<Capabilities>
<DeviceCapability Name="location"/>
</Capabilities>
Tip
對於未封裝的應用程式,清單中不需要位置功能。 不過,你仍然必須呼叫 RequestAccessAsync 來提示使用者取得許可。
取得目前的位置
請依照以下步驟執行單次位置讀取。
請求存取使用者位置
在存取位置資料前,請先先聯絡 Geolocator.RequestAccessAsync 。 此方法在首次執行時會提示使用者取得權限。 你必須在應用程式位於前景時,從 UI 執行緒呼叫它。
using Windows.Devices.Geolocation;
var accessStatus = await Geolocator.RequestAccessAsync();
請閱讀立場
如果使用者授予權限,請建立 Geolocator 並呼叫 GetGeopositionAsync,以取得一次性的位置資訊。
switch (accessStatus)
{
case GeolocationAccessStatus.Allowed:
var geolocator = new Geolocator { DesiredAccuracyInMeters = 50 };
Geoposition position = await geolocator.GetGeopositionAsync();
double latitude = position.Coordinate.Point.Position.Latitude;
double longitude = position.Coordinate.Point.Position.Longitude;
StatusText.Text = $"Location: {latitude:F4}, {longitude:F4}";
break;
case GeolocationAccessStatus.Denied:
StatusText.Text = "Location access is denied.";
break;
case GeolocationAccessStatus.Unspecified:
StatusText.Text = "An unspecified error occurred.";
break;
}
追蹤使用者位置隨時間的變化
欲定期接收位置更新,請訂閱 PositionChanged 活動。 設定 ReportInterval 用於時間追蹤,或設定 MovementThreshold 用於距離追蹤。
if (accessStatus == GeolocationAccessStatus.Allowed)
{
var geolocator = new Geolocator { ReportInterval = 2000 }; // 2-second interval
geolocator.PositionChanged += OnPositionChanged;
geolocator.StatusChanged += OnStatusChanged;
}
處理位置更新
PositionChanged事件會在背景線程觸發。 用 DispatcherQueue 來將 UI 更新匯回主執行緒。
private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
DispatcherQueue.TryEnqueue(() =>
{
var position = args.Position.Coordinate.Point.Position;
StatusText.Text = $"Updated: {position.Latitude:F4}, {position.Longitude:F4}";
});
}
處理狀態變更
監控 狀態變更 以偵測使用者何時關閉定位服務或 GPS 訊號中斷。
private void OnStatusChanged(Geolocator sender, StatusChangedEventArgs args)
{
DispatcherQueue.TryEnqueue(() =>
{
switch (args.Status)
{
case PositionStatus.Ready:
StatusText.Text = "Location is available.";
break;
case PositionStatus.Disabled:
StatusText.Text = "Location is disabled. Check Settings.";
break;
case PositionStatus.NoData:
StatusText.Text = "Unable to determine location.";
break;
case PositionStatus.NotAvailable:
StatusText.Text = "Location is not available on this device.";
break;
}
});
}
引導使用者前往位置設定
如果使用者拒絕存取位置,請提供 Windows 隱私設定的連結,讓他們可以更改偏好設定。
<HyperlinkButton Content="Open location settings"
NavigateUri="ms-settings:privacy-location" />
你也可以從程式碼開啟設定頁面:
await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
在地圖上顯示位置
取得位置後,您可以藉由設定其 Center 並新增 MapIcon,將其顯示在 WinUI 3 的 MapControl 上。 若想看結合地理定位、地圖顯示與地理圍欄的完整工作範例,請參見 地圖與位置概述。
Troubleshooting
如果您的應用程式無法取得位置,請在 設定 > 隱私與安全 > 位置中確認以下事項:
- 定位服務已開啟。
- 你的應用程式在「讓應用程式存取你的位置」下被列為開啟。
- 裝置配備可運作的GPS接收器或網路定位功能。