次の方法で共有


地理位置情報

サンプルを参照します。 サンプルを参照する

この記事では、.NET マルチプラットフォーム アプリ UI (.NET MAUI) ITextToSpeech インターフェイスを使用する方法について説明します。 このインターフェイスは、デバイスの現在の位置情報座標を取得するための API を提供します。

IGeolocation インターフェイスの既定の実装は、Geolocation.Default プロパティを使用して使用できます。 IGeolocation インターフェイスと Geolocation クラスの両方が、Microsoft.Maui.Devices.Sensors 名前空間に含まれています。

始めましょう

位置情報機能にアクセスするには、次のプラットフォーム固有のセットアップが必要です。

粗い位置情報または詳細な位置情報のアクセス許可、またはその両方を指定する必要があり、Androidプロジェクト内で構成する必要があります。

さらに、アプリが Android 5.0 (API レベル 21) 以降を対象とする場合は、アプリでマニフェスト ファイル内のハードウェア機能を使用することを宣言する必要があります。 これは、次の方法で追加できます。

  • アセンブリ ベースのアクセス許可を追加します。

    Platforms/Android/MainApplication.cs ファイルを開き、using ディレクティブの後に次のアセンブリ属性を追加します。

    [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
    [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
    [assembly: UsesFeature("android.hardware.location", Required = false)]
    [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
    [assembly: UsesFeature("android.hardware.location.network", Required = false)]
    

    アプリケーションが Android 10 - Q (API レベル 29 以上) を対象としており、 LocationAlwaysを要求している場合は、次のアクセス許可要求も追加する必要があります。

    [assembly: UsesPermission(Android.Manifest.Permission.AccessBackgroundLocation)]
    

    -又は-

  • Android マニフェストを更新します。

    Platforms/Android/AndroidManifest.xml ファイルを開き、manifest ノードに次を追加します。

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-feature android:name="android.hardware.location" android:required="false" />
    <uses-feature android:name="android.hardware.location.gps" android:required="false" />
    <uses-feature android:name="android.hardware.location.network" android:required="false" />
    

    アプリケーションが Android 10 - Q (API レベル 29 以上) を対象としており、 LocationAlwaysを要求している場合は、次のアクセス許可要求も追加する必要があります。

    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    

    -又は-

  • マニフェスト エディターで Android マニフェストを更新します。

    Visual Studio で Platforms/Android/AndroidManifest.xml ファイルをダブルクリックして、Android マニフェスト エディターを開きます。 次に、[ 必要なアクセス許可 ] で、上記のアクセス許可を確認します。 これにより、AndroidManifest.xml ファイルが自動的に更新されます。

ヒント

考慮する必要がある多くの制限があるため、 バックグラウンドの場所の更新に関する Android ドキュメントを必ず読んでください。

最後の既知の場所を取得する

デバイスは、デバイスの最新の場所をキャッシュしている可能性があります。 キャッシュされた場所 (使用可能な場合) にアクセスするには、 GetLastKnownLocationAsync() メソッドを使用します。 これは、多くの場合、完全な場所のクエリを実行するよりも高速ですが、精度が低くなる可能性があります。 キャッシュされた場所が存在しない場合、このメソッドは nullを返します。

必要に応じて、Geolocation API によってユーザーにアクセス許可の入力を求められます。

次のコード例は、キャッシュされた場所のチェックを示しています。

public async Task<string> GetCachedLocation()
{
    try
    {
        Location location = await Geolocation.Default.GetLastKnownLocationAsync();

        if (location != null)
            return $"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}";
    }
    catch (FeatureNotSupportedException fnsEx)
    {
        // Handle not supported on device exception
    }
    catch (FeatureNotEnabledException fneEx)
    {
        // Handle not enabled on device exception
    }
    catch (PermissionException pEx)
    {
        // Handle permission exception
    }
    catch (Exception ex)
    {
        // Unable to get location
    }

    return "None";
}

デバイスによっては、すべての場所の値が使用できるわけではありません。 たとえば、 Altitude プロパティは、 null、値 0、または海抜メートルを示す正の値を持つ場合があります。 存在しない可能性があるその他の値には、 Speed プロパティと Course プロパティが含まれます。

現在の場所を取得する

デバイスの最後の 既知の場所 を確認する方が速くなる場合があり、不正確になる可能性があります。 GetLocationAsyncメソッドを使用して、デバイスに現在の場所を照会します。 クエリの精度とタイムアウトを構成できます。 GeolocationRequestパラメーターとCancellationToken パラメーターを使用するメソッド オーバーロードに最適です。デバイスの場所を取得するには時間がかかる場合があるためです。

必要に応じて、Geolocation API によってユーザーにアクセス許可の入力を求められます。

次のコード例は、キャンセルをサポートしながら、デバイスの場所を要求する方法を示しています。

private CancellationTokenSource _cancelTokenSource;
private bool _isCheckingLocation;

public async Task GetCurrentLocation()
{
    try
    {
        _isCheckingLocation = true;

        GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));

        _cancelTokenSource = new CancellationTokenSource();

        Location location = await Geolocation.Default.GetLocationAsync(request, _cancelTokenSource.Token);

        if (location != null)
            Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
    }
    // Catch one of the following exceptions:
    //   FeatureNotSupportedException
    //   FeatureNotEnabledException
    //   PermissionException
    catch (Exception ex)
    {
        // Unable to get location
    }
    finally
    {
        _isCheckingLocation = false;
    }
}

public void CancelRequest()
{
    if (_isCheckingLocation && _cancelTokenSource != null && _cancelTokenSource.IsCancellationRequested == false)
        _cancelTokenSource.Cancel();
}

デバイスによっては、すべての場所の値が使用できるわけではありません。 たとえば、 Altitude プロパティは、 null、値 0、または海抜メートルを示す正の値を持つ場合があります。 存在しない可能性があるその他の値には、 SpeedCourseがあります。

警告

GetLocationAsync は、一部のシナリオで null を返すことができます。 これは、基になるプラットフォームが現在の場所を取得できないことを示します。

位置の変更を監視する

現在の場所についてデバイスに対してクエリを実行するだけでなく、アプリがフォアグラウンドにある間に場所の変更をリッスンできます。

アプリが現在場所の変更をリッスンしているかどうかを確認するには、クエリを実行できる IsListeningForeground プロパティがあります。 場所の変更を検知する準備ができたら、StartListeningForegroundAsync メソッドを呼び出してください。 このメソッドは、場所の更新のリッスンを開始し、アプリがフォアグラウンドにある場合、場所が変更されたときに LocationChanged イベントを発生させます。 このイベントに付随するGeolocationLocationChangedEventArgs オブジェクトには、検出された新しい場所を表すLocation型のLocation プロパティがあります。

必要に応じて、Geolocation API によってユーザーにアクセス許可の入力を求められます。

次のコード例は、場所の変更をリッスンする方法と、変更された場所を処理する方法を示しています。

async void OnStartListening()
{
    try
    {
        Geolocation.LocationChanged += Geolocation_LocationChanged;
        var request = new GeolocationListeningRequest((GeolocationAccuracy)Accuracy);
        var success = await Geolocation.StartListeningForegroundAsync(request);

        string status = success
            ? "Started listening for foreground location updates"
            : "Couldn't start listening";
    }
    catch (Exception ex)
    {
        // Unable to start listening for location changes
    }
}

void Geolocation_LocationChanged(object sender, GeolocationLocationChangedEventArgs e)
{
    // Process e.Location to get the new location
}

エラー処理は、 ListeningFailed イベントのイベント ハンドラーを登録することによって実装できます。 このイベントに付随する GeolocationListeningFailedEventArgs オブジェクトには、リッスンが失敗した理由を示す Error プロパティ ( GeolocationError 型) があります。 ListeningFailed イベントが発生すると、位置変更の監視が停止し、それ以降LocationChangedイベントは発生しません。

場所の変更を追跡することを停止するには、StopListeningForeground メソッドを呼び出します。

void OnStopListening()
{
    try
    {
        Geolocation.LocationChanged -= Geolocation_LocationChanged;
        Geolocation.StopListeningForeground();
        string status = "Stopped listening for foreground location updates";
    }
    catch (Exception ex)
    {
        // Unable to stop listening for location changes
    }
}

StopListeningForeground メソッドは、アプリが場所の変更をリッスンしていない場合には影響しません。

位置情報サービスが有効になっているかどうかを確認する

Geolocation クラスには、デバイスで位置情報サービスが有効になっているかどうかを判断するために使用できる読み取り専用のIsEnabled プロパティがあります。

精度

次のセクションでは、プラットフォームごとの位置精度の距離について説明します。

重要

iOS には、精度に関するいくつかの制限があります。 詳細については、「 プラットフォームの相違点」セクションを 参照してください。

最低

プラットホーム 距離 (メートル単位)
アンドロイド 500
iOS 3000
ウィンドウズ 1000 - 5000

プラットホーム 距離 (メートル単位)
アンドロイド 500
iOS 1000
ウィンドウズ 300 - 3000

中 (既定値)

プラットホーム 距離 (メートル単位)
アンドロイド 100 - 500
iOS 100
ウィンドウズ 30-500

プラットホーム 距離 (メートル単位)
アンドロイド 0 - 100
iOS 10
ウィンドウズ <= 10

最高

プラットホーム 距離 (メートル単位)
アンドロイド 0 - 100
iOS ~0
ウィンドウズ <= 10

偽の位置情報の検出

一部のデバイスは、位置情報プロバイダーやテスト用の位置情報を提供するアプリケーションからテスト用の位置情報を返すことがあります。 これは、任意のIsFromMockProviderLocationを使用して検出できます。

public async Task CheckMock()
{
    GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium);
    Location location = await Geolocation.Default.GetLocationAsync(request);

    if (location != null && location.IsFromMockProvider)
    {
        // location is from a mock provider
    }
}

2 つの場所間の距離

CalculateDistanceメソッドは、2 つの地理的位置間の距離を計算します。 この計算された距離は、道路やその他の経路を考慮に入れるのではなく、地球表面に沿った 2 つのポイント間の最短距離にすぎません。 この計算は、 大円距離 計算と呼ばれます。

次のコードは、米国のボストン市とサンフランシスコ市間の距離を計算します。

Location boston = new Location(42.358056, -71.063611);
Location sanFrancisco = new Location(37.783333, -122.416667);

double miles = Location.CalculateDistance(boston, sanFrancisco, DistanceUnits.Miles);

Location(Double, Double, Double) コンストラクターは、それぞれ緯度と経度の引数を受け入れます。 正の緯度の値は赤道の北にあり、正の経度の値はプライム子午線の東です。 最後の引数を使用して CalculateDistance マイルまたはキロメートルを指定します。 UnitConverters クラスは、2 つの単位間で変換するためのKilometersToMilesメソッドとMilesToKilometers メソッドも定義します。

プラットフォームの違い

このセクションでは、位置情報 API とのプラットフォーム固有の違いについて説明します。

高度はプラットフォームごとに異なる方法で計算されます。

Android では、 高度 (使用可能な場合) は WGS 84 参照楕円体の上のメートルで返されます。 この場所に高度がない場合は、 0.0 が返されます。

Location.ReducedAccuracy プロパティは iOS でのみ使用され、他のすべてのプラットフォームでfalseを返します。