地理圍欄是以某個興趣點為中心所劃定的圓形地理邊界。 當使用者進入或離開邊界時,應用程式會收到通知。 地理圍欄對於以位置為基礎的提醒、警示、簽到,以及依情境提供內容都很有用。
本文說明如何在 Windows 應用程式 SDK(WinUI 3)應用程式中建立地理圍欄、監控狀態變化,以及處理地理圍欄事件。
先決條件
- 這是一個由 Blank App, Packaged(桌面版 WinUI 3) 範本建立的 WinUI 3 專案。
- 套件資訊清單中宣告的 位置 功能。 請參閱 「取得使用者位置 」以獲得指示。
請求位置存取權限
在建立或監控地理圍欄前,請先聯絡 Geolocator.RequestAccessAsync 。
using Windows.Devices.Geolocation;
using Windows.Devices.Geolocation.Geofencing;
var accessStatus = await Geolocator.RequestAccessAsync();
if (accessStatus != GeolocationAccessStatus.Allowed)
{
StatusText.Text = "Location access is required for geofencing.";
return;
}
建立地理柵欄
定義地理圍欄時,請指定識別碼、地理中心、半徑(公尺)以及要監控的狀態轉換(輸入、退出或移除)。
var position = new BasicGeoposition
{
Latitude = 47.6062,
Longitude = -122.3321
};
var geocircle = new Geocircle(position, 200); // 200-meter radius
var geofence = new Geofence(
"SeattleDowntown", // Unique identifier
geocircle, // Geographic boundary
MonitoredGeofenceStates.Entered | // States to monitor
MonitoredGeofenceStates.Exited,
false, // Single use: false = persistent
TimeSpan.FromSeconds(10) // Dwell time before triggering
);
GeofenceMonitor.Current.Geofences.Add(geofence);
地質柵參數
| Parameter | 說明 |
|---|---|
id |
用來識別地理圍欄的唯一字串。 使用此功能來區分來自不同地理圍欄的事件。 |
geoshape |
一個定義邊界的 地圓 圖。 僅支援圓形邊界。 |
monitoredStates |
哪個轉換會被監控: Entered、、 Exited或 Removed。 與 | 運算子結合。 |
singleUse |
若 true,地理柵欄會觸發一次,並自動刪除。 |
dwellTime |
使用者必須在邊界內(或外)停留多久,事件才會被觸發。 有助於過濾短暫的過河。 |
在前景中監控地理圍欄事件
訂閱 GeofenceMonitor.Current.GeofenceStateChanged 事件,即可在應用程式運行時接收通知。
GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;
閱讀報告並更新使用者介面。 事件會在背景執行緒觸發,所以用 DispatcherQueue 來執行 UI 更新。
private void OnGeofenceStateChanged(GeofenceMonitor sender, object args)
{
var reports = sender.ReadReports();
DispatcherQueue.TryEnqueue(() =>
{
foreach (var report in reports)
{
var state = report.NewState;
var id = report.Geofence.Id;
switch (state)
{
case GeofenceState.Entered:
StatusText.Text = $"Entered geofence: {id}";
break;
case GeofenceState.Exited:
StatusText.Text = $"Exited geofence: {id}";
break;
case GeofenceState.Removed:
StatusText.Text = $"Geofence removed: {id}";
// Re-add the geofence if it was removed due to expiration
break;
}
}
});
}
監控地理圍欄狀態變更
使用 GeofenceMonitor.Current.StatusChanged 來偵測地理圍欄監控是否被停用——例如當使用者關閉位置服務時。
GeofenceMonitor.Current.StatusChanged += (sender, args) =>
{
DispatcherQueue.TryEnqueue(() =>
{
var status = sender.Status;
if (status == GeofenceMonitorStatus.Disabled)
{
StatusText.Text = "Geofence monitoring is disabled. Check location settings.";
}
});
};
Tip
使用地理圍欄時,請透過 GeofenceMonitor.StatusChanged 監控權限變更,而非 Geolocator.StatusChanged。
GeofenceMonitorStatus 的值為 Disabled 時,相當於 PositionStatus 的值為 Disabled,但 GeofenceMonitorStatus 可為地理圍欄情境提供更多脈絡。
移除地理圍欄
在 GeofenceMonitor.Current.Geofences 集合中找到地理圍欄,移除它。
var geofences = GeofenceMonitor.Current.Geofences;
var target = geofences.FirstOrDefault(g => g.Id == "SeattleDowntown");
if (target != null)
{
geofences.Remove(target);
}
最佳做法
- 設定合理的停留時間。 至少 10 秒的停留時間有助於過濾 GPS 抖動,並防止邊界邊緣的誤觸發。
- 使用至少 50 公尺的半徑。 GPS 的準確度會因裝置和環境而異。 半徑小於50公尺的結果可能不可靠。
- 如果需要,請檢查網路連線。 如果您的應用程式在地理圍欄事件觸發時執行網路操作(例如向伺服器發送通知),請在建立地理圍欄前先驗證連線性。
- 處理
Removed狀態。 若地防柵過期或系統面臨資源壓力,系統可將其移除。 請檢查GeofenceState.Removed,並在您的情境需要時重新建立地理圍欄。 - 除非必要,不要同時監控同一個地理圍欄的前景和背景。 如果有,請在應用程式暫停時取消註冊前景監聽器,恢復時再重新註冊。