다음을 통해 공유


지리적 위치

Browse sample. 샘플 찾아보기

이 문서에서는 .NET 다중 플랫폼 앱 UI(.NET MAUI) IGeolocation 인터페이스를 사용하는 방법을 설명합니다. 이 인터페이스는 디바이스의 현재 지리적 위치 좌표를 검색하는 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에서 플랫폼/Android/AndroidManifest.xml 파일을 두 번 클릭하여 Android 매니페스트 편집기를 엽니다. 그런 다음, 필수 사용 권한에서 위에 나열된 사용 권한을 검사. 그러면 AndroidManifest.xml 파일이 자동으로 업데이트됩니다.

고려해야 할 많은 제한 사항이 있으므로 백그라운드 위치 업데이트에 대한 Android 설명서를 읽어야 합니다.

마지막으로 알려진 위치 가져오기

디바이스가 디바이스의 가장 최근 위치를 캐시했을 수 있습니다. GetLastKnownLocationAsync() 사용 가능한 경우 메서드를 사용하여 캐시된 위치에 액세스합니다. 전체 위치 쿼리를 수행하는 것보다 빠른 경우가 많지만 정확도가 낮을 수 있습니다. 캐시된 위치가 없으면 이 메서드가 반환됩니다 null.

참고 항목

필요한 경우 지리적 위치 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 이 0이거나 해발 미터를 나타내는 양수 값이 있을 null수 있습니다. 존재하지 않을 수 있는 다른 값에는 해당 값과 Course 속성이 Speed 포함됩니다.

현재 위치 가져오기

디바이스의 마지막으로 알려진 위치에 대한 검사 더 빠를 수 있지만 정확하지 않을 수 있습니다. 이 메서드를 GetLocationAsync 사용하여 디바이스에서 현재 위치를 쿼리합니다. 쿼리의 정확도 및 시간 제한을 구성할 수 있습니다. 디바이스의 위치를 가져오는 데 다소 시간이 걸릴 수 있으므로 매개 변수 및 CancellationToken 매개 변수를 사용하는 GeolocationRequest 메서드 오버로드에 가장 적합합니다.

참고 항목

필요한 경우 지리적 위치 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 이 0이거나 해발 미터를 나타내는 양수 값이 있을 null수 있습니다. 존재하지 않을 수 있는 다른 값으로는 SpeedCourse가 있습니다.

Warning

GetLocationAsync 는 일부 시나리오에서 반환 null 할 수 있습니다. 이는 기본 플랫폼이 현재 위치를 가져올 수 없음을 나타냅니다.

위치 변경 수신 대기

디바이스에서 현재 위치를 쿼리하는 것 외에도 앱이 포그라운드에 있는 동안 위치 변경 내용을 수신 대기할 수 있습니다.

앱이 현재 위치 변경 내용을 수신 대기하고 있는지 확인하기 위해 검사 쿼리할 수 있는 속성이 IsListeningForeground 있습니다. 위치 변경 내용 수신 대기를 시작할 준비가 되면 메서드를 StartListeningForegroundAsync 호출해야 합니다. 이 메서드는 위치 업데이트를 수신 대기하기 시작하고 앱이 LocationChanged 포그라운드에 있는 경우 위치가 변경될 때 이벤트를 발생합니다. GeolocationLocationChangedEventArgs 이 이벤트와 함께 제공되는 개체에는 Location 검색된 새 위치를 나타내는 형식Location의 속성이 있습니다.

참고 항목

필요한 경우 지리적 위치 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 앱이 위치 변경 내용을 수신 대기하지 않는 경우 메서드는 영향을 주지 않습니다.

정확도

다음 섹션에서는 플랫폼당 위치 정확도 거리를 간략하게 설명합니다.

Important

iOS에는 정확도에 대한 몇 가지 제한 사항이 있습니다. 자세한 내용은 플랫폼 차이점 섹션을 참조하세요 .

가장 낮음

플랫폼 거리(미터)
Android 500
iOS 3000
Windows 1000 - 5000

낮음

플랫폼 거리(미터)
Android 500
iOS 1000
Windows 300 - 3000

중간(기본값)

플랫폼 거리(미터)
Android 100 - 500
iOS 100
Windows 30-500

높음

플랫폼 거리(미터)
Android 0 - 100
iOS 10
Windows <= 10

가장 좋음

플랫폼 거리(미터)
Android 0 - 100
iOS ~0
Windows <= 10

모의 위치 검색

일부 디바이스는 공급자에서 또는 모의 위치를 제공하는 애플리케이션에 의해 모의 위치를 반환할 수 있습니다. 다음 항목을 Location사용하여 이를 감지할 IsFromMockProvider 수 있습니다.

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
    }
}

두 위치 사이의 거리

이 메서드는 CalculateDistance 두 지리적 위치 사이의 거리를 계산합니다. 이 계산된 거리는 도로나 다른 통로를 고려하지 않으며 지구 표면을 따라 두 지점 사이의 가장 짧은 거리에 불과합니다. 이 계산을 원 거리 계산이라고도합니다.

다음 코드는 보스턴과 샌프란시스코의 미국 도시 미국 사이의 거리를 계산합니다.

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 클래스는 두 단위 간에 변환하기 위한 KilometersToMilesMilesToKilometers 메서드를 정의합니다.

플랫폼 간 차이점

이 섹션에서는 지리적 위치 API와 플랫폼별 차이점에 대해 설명합니다.

고도는 플랫폼마다 다르게 계산됩니다.

Android에서 사용 가능한 경우 고도는 WGS 84 참조 타원면 위에 미터 단위로 반환됩니다. 이 위치에 고도 0.0 가 없으면 반환됩니다.

Location.ReducedAccuracy 속성은 iOS에서만 사용되며 다른 모든 플랫폼에서 반환 false 됩니다.