maui-geolocation について
.NET MAUI の位置情報機能に関する実用ガイドです。権限処理、精度とバッテリー消費の兼ね合い、キャンセル、プラットフォームごとの動作、継続追跡の終了処理を説明します。
主な機能
- 01キャンセルとタイムアウトの指針
- 02精度とバッテリー消費の兼ね合い
- 03プラットフォーム別の権限処理
- 04最終位置情報からのフォールバック
- 05継続追跡の終了処理
活用シーン
- 01位置情報リクエストへのタイムアウト追加
- 02概算位置や位置情報の取得失敗への対応
- 03位置情報を使うセキュリティチェックの実装
- 04GPS を使い続けないよう継続追跡を終了
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-geolocationインストール後、Claude Code で/maui-geolocationを入力して読み込まれたか確認します。
同梱ファイルreferences/geolocation-api.md
詳細
.NET MAUI Geolocation
重要:必ず CancellationToken を渡してください
GPS がオフになっている場合、デバイスが屋内にある場合、または権限が保留状態の場合、GetLocationAsync はいつまでも終了しないことがあります。必ずタイムアウトを設定してください。
// ❌ Hangs forever if no GPS fix is available
var location = await Geolocation.Default.GetLocationAsync(
new GeolocationRequest(GeolocationAccuracy.High));
// ✅ Times out after 30 seconds
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var location = await Geolocation.Default.GetLocationAsync(
new GeolocationRequest(GeolocationAccuracy.High), cts.Token);
精度とバッテリー消費のトレードオフ
機能を満たす範囲で、最も低い精度を使用してください。精度を高くすると、バッテリーの消費が大幅に速くなります。特に Android では顕著です。
| ユースケース | 推奨される精度 |
|---|---|
| 市区町村レベル/天気 | Lowest または Low |
| 近くの場所の検索/店舗検索 | Medium |
| ターンバイターン方式のナビゲーション | High または Best |
プラットフォーム固有の注意点
iOS 14 の精度制限
ユーザーは「おおよその位置情報」(精度 > 1 km)を許可できます。アプリは位置情報を受け取りますが、精度が求められる機能には使えない可能性があります。
location.Accuracyを確認してください。値が 100 m を超える場合、精度が制限されている可能性があります。Info.plistのNSLocationTemporaryUsageDescriptionDictionaryに対応するキーを指定してGeolocationRequest.RequestFullAccuracyを使用し、正確な位置情報の利用を求めてください。
Android:セキュリティが重要なフローでのモック位置情報
// ⚠️ Always check in security-sensitive flows (e.g., geofence, check-in)
if (location.IsFromMockProvider)
{
// Reject — user is spoofing location
}
Android:Altitude が 0.0 でも海抜とは限りません
一部の Android デバイスでは、GPS に気圧センサーがない場合、Altitude に 0.0 が返されます。0.0 は海抜ではなく、**「不明」**として扱ってください。
Android 10 以降:バックグラウンド位置情報には別途権限が必要です
ACCESS_BACKGROUND_LOCATION はフォアグラウンドの権限とは別にリクエストする必要があり、システムのダイアログも個別に表示されます。フォアグラウンドの権限と同時にリクエストすると、一部のデバイスでは両方とも拒否されます。
GetLastKnownLocationAsync が null を返す場合
初回起動時や位置情報データのリセット後には、これは想定される動作です。必ず GetLocationAsync にフォールバックしてください。
// ✅ Cache-first with fresh fallback
var location = await geolocation.GetLastKnownLocationAsync();
if (location is null || location.Timestamp < DateTimeOffset.UtcNow.AddMinutes(-5))
{
location = await geolocation.GetLocationAsync(
new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10)), ct);
}
測位を呼び出す前に権限をリクエストする必要があります
最初に Permissions.RequestAsync<Permissions.LocationWhenInUse>() を呼び出すか、PermissionException をキャッチしてください。権限なしで GetLocationAsync を呼び出すと、一部のプラットフォームでは例外がスローされ、ほかのプラットフォームでは null が返されるため、プラットフォーム間で動作が一貫しません。
継続的な位置情報の取得:登録解除を忘れないでください
停止時に LocationChanged ハンドラーを解除しないと、GPS が使われ続け、バッテリーを消費します。
// ❌ Forgetting to unsubscribe — GPS stays active
public void StopTracking()
{
Geolocation.Default.StopListeningForeground();
// LocationChanged handler still fires!
}
// ✅ Always remove the event handler
public void StopTracking()
{
Geolocation.Default.StopListeningForeground();
Geolocation.Default.LocationChanged -= OnLocationChanged;
}
チェックリスト
- すべての
GetLocationAsync呼び出しにCancellationTokenを渡している - 機能の要件に合わせて精度レベルを選んでいる(無条件に
Bestを設定していない) -
GetLastKnownLocationAsyncの戻り値をnullチェックし、GetLocationAsyncにフォールバックしている - 初回の測位呼び出し前に実行時権限をリクエストしている
- 継続的な位置情報の取得を停止するときに
LocationChangedハンドラーを解除している - Android:必要に応じて
ACCESS_BACKGROUND_LOCATIONを個別にリクエストしている - iOS:正確な位置情報を求めるダイアログのために
NSLocationTemporaryUsageDescriptionDictionaryを追加している - Android:セキュリティが重要なフローで
IsFromMockProviderを確認している