Aracılığıyla paylaş


Coğrafi konum

Örneğe göz atın. Örneğe göz atın

Bu makalede .NET Çok Platformlu Uygulama Kullanıcı Arabirimi (.NET MAUI) IGeolocation arabirimini nasıl kullanabileceğiniz açıklanmaktadır. Bu arayüz, cihazın mevcut coğrafi konum koordinatlarını almak için API'ler sağlar.

IGeolocation arabiriminin varsayılan uygulaması Geolocation.Default özelliği aracılığıyla kullanılabilir. hem IGeolocation arabirimi hem de Geolocation sınıfı Microsoft.Maui.Devices.Sensors ad alanında yer alır.

Başlayın

Geolocation işlevine erişmek için, aşağıdaki platforma özgü kurulum gereklidir:

Kaba veya hassas konum izinleri veya her ikisi belirtilmeli ve Android projesinde yapılandırılmalıdır.

Ek olarak, uygulamanız Android 5.0 (API seviyeleri 21) veya üstünü hedefliyorsa, uygulamanızın donanım özelliklerini kullandığını manifest dosyasında belirtmelisiniz. Bu, aşağıdaki yollarla eklenebilir:

  • Add the assembly-based permission:

    Platformları/Android/MainApplication.cs dosyasını açın ve using yönergelerinden sonra aşağıdaki derleme özniteliklerini ekleyin:

    [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)]
    

    Uygulamanız Android 10 - Q (API Düzeyi 29 veya üstü) hedefliyorsa ve LocationAlways isteniyorsa, bu izin isteğini de eklemeniz gerekmektedir:

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

    -veya-

  • Android Bildirimini güncelleştirin:

    Platformları/Android/AndroidManifest.xml dosyasını açın ve manifest düğümüne aşağıdakileri ekleyin:

    <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" />
    

    Uygulamanız Android 10 - Q (API Düzeyi 29 veya daha yüksek) hedefliyorsa ve LocationAlways talep ediyorsa, bu izin isteğini de eklemelisiniz:

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

    -veya-

  • Bildirim düzenleyicisinde Android Bildirimi'ni güncelleştirin:

    Visual Studio'da Platformlar/Android/AndroidManifest.xml dosyasına çift tıklayarak Android bildirim düzenleyicisini açın. Ardından, Gerekli izinler altında yukarıda belirtilen izinleri kontrol edin. Bu, AndroidManifest.xml dosyasını otomatik olarak güncelleştirir.

Tavsiye

Arka plan konum güncellemeleri ile ilgili Android belgelerini mutlaka okuyun, çünkü dikkate alınması gereken birçok kısıtlama vardır.

Son bilinen konumu al

Cihaz, cihazın en son konumunu önbelleğe almış olabilir. Mevcutsa önbelleğe alınmış konuma erişmek için GetLastKnownLocationAsync() yöntemini kullanın. Bu, genellikle tam bir konum sorgusu yapmaktan daha hızlıdır, ancak daha az doğru olabilir. Önbellekte konum yoksa, bu yöntem null döndürür.

Uyarı

Gerekli olduğunda, Coğrafi Konum API'si kullanıcıdan izinler ister.

Aşağıdaki kod örneği, önbelleğe alınmış bir konumu kontrol etmeyi gösterir:

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

Cihaza bağlı olarak, tüm konum değerleri mevcut olmayabilir. Örneğin, Altitude özelliği null olabilir, değeri 0 olabilir veya deniz seviyesinin üzerindeki metreleri gösteren pozitif bir değere sahip olabilir. Diğer mevcut olmayabilecek değerler arasında Speed ve Course özellikleri bulunmaktadır.

Geçerli konumu al.

Cihazın son bilinen konumunu kontrol etmek daha hızlı olabilir, ancak doğru olmayabilir. Mevcut konumu öğrenmek için cihazı sorgulamak üzere GetLocationAsync yöntemini kullanın. Yapılandırma kesinliğini ve sorgu zaman aşımını ayarlayabilirsiniz. En iyisi, aygıtın konumunu almak biraz zaman alabileceğinden, GeolocationRequest ve CancellationToken parametrelerini kullanan yöntem aşırı yüklemesini kullanmaktır.

Uyarı

Gerektiğinde, Konum API'si kullanıcıdan izin ister.

Aşağıdaki kod örneği, iptali destekleyerek cihazın konumunu nasıl isteyeceğinizi gösterir:

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();
}

Cihaza bağlı olarak tüm konum değerleri mevcut olmayabilir. Örneğin, Altitude özelliği null olabilir, değeri 0 olabilir veya deniz seviyesinin üzerinde metreleri gösteren pozitif bir değere sahip olabilir. Mevcut olmayabilecek diğer değerler arasında Speed ve Course bulunmaktadır.

Uyarı

GetLocationAsync, bazı senaryolarda null döndürebilir. Bu, temel platformun mevcut konumu elde edemediğini gösterir.

Konum değişikliklerini dinle

Cihazın mevcut konumunu sorgulamanın yanı sıra, bir uygulama ön plandayken konum değişikliklerini dinleyebilirsiniz.

Uygulamanın konum değişikliklerini dinleyip dinlemediğini kontrol etmek için, sorgulayabileceğiniz bir IsListeningForeground özelliği vardır. Konum değişikliklerini dinlemeye başlamaya hazır olduğunuzda, StartListeningForegroundAsync yöntemini çağırmalısınız. Bu yöntem, konum güncellemelerini dinlemeye başlar ve uygulama ön planda olduğu sürece konum değiştiğinde LocationChanged olayını tetikler. Bu olaya eşlik eden GeolocationLocationChangedEventArgs nesnesi, bulunan yeni konumu temsil eden bir Location türünde Location özelliğine sahiptir.

Uyarı

Gerektiğinde, Konum API'si kullanıcıdan izin ister.

Aşağıdaki kod örneği, bir konum değişikliğinin nasıl dinleneceğini ve değişen konumun nasıl işleneceğini göstermektedir.

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
}

Hata yönetimi, ListeningFailed olayı için bir olay işleyici kaydederek gerçekleştirilebilir. Bu olaya eşlik eden GeolocationListeningFailedEventArgs nesnesi, dinlemenin neden başarısız olduğunu belirten bir GeolocationError türünde Error özelliğine sahiptir. ListeningFailed olayı tetiklendiğinde, konum değişiklikleri için dinleme durur ve başka LocationChanged olayları tetiklenmez.

Konum değişikliklerini dinlemeyi durdurmak için StopListeningForeground yöntemini çağırın.

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

Uyarı

StopListeningForeground yöntemi, uygulama konum değişikliklerini dinlemiyorsa hiçbir etki göstermez.

Konum servislerinin etkin olup olmadığını kontrol edin

Geolocation sınıfı, cihazda konum servislerinin etkinleştirilip etkinleştirilmediğini belirlemek için kullanılabilecek salt okunur bir IsEnabled özelliğine sahiptir.

Doğruluk

Aşağıdaki bölümler, her platform için konum doğruluğu mesafesini açıklar:

Önemli

iOS'un doğruluk konusunda bazı sınırlamaları vardır. Daha fazla bilgi için Platform farkları bölümüne bakın.

En düşük

Platform Distance (in meters)
Android beş yüz
Ios 3000
Windows 1000 - 5000

Düşük

Platform Distance (in meters)
Android beş yüz
Ios 1000
Windows 300 - 3000

Orta (Varsayılan)

Platform Distance (in meters)
Android 100 - 500
Ios 100
Windows 30-500

Yüksek

Platform Distance (in meters)
Android 0 - 100
Ios 10
Windows <= 10

En iyi

Platform Distance (in meters)
Android 0 - 100
Ios ~0
Windows <= 10

Sahte konumları algılama

Bazı cihazlar, sağlayıcıdan veya sahte konumlar sunan bir uygulama tarafından sahte bir konum döndürebilir. Bu durumu IsFromMockProvider herhangi bir Location üzerinde kullanarak tespit edebilirsiniz.

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

İki konum arasındaki mesafe

CalculateDistance yöntemi, iki coğrafi konum arasındaki mesafeyi hesaplar. Hesaplanan bu mesafe, yolları veya diğer geçitleri dikkate almaz ve sadece yer yüzeyinde iki nokta arasındaki en kısa mesafedir. Bu hesaplama, büyük daire mesafesi hesaplaması olarak bilinir.

Aşağıdaki kod, Amerika Birleşik Devletleri'ne bağlı Boston ve San Francisco şehirleri arasındaki mesafeyi hesaplar.

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) yapıcı, sırasıyla enlem ve boylam argümanlarını alır. Ekvator'un kuzeyindeki enlem değerleri pozitif; Baş Meridyen'in doğusundaki boylam değerleri pozitif olarak kabul edilir. CalculateDistance öğesinin son argümanını mil veya kilometre belirtmek için kullanın. UnitConverters sınıfı, iki birim arasında dönüştürme yapmak için KilometersToMiles ve MilesToKilometers yöntemlerini de tanımlar.

Platform farklılıkları

Bu bölüm, coğrafi konum API'si ile platforma özgü farklılıkları tanımlar.

İrtifa her platformda farklı şekilde hesaplanır.

Android'de, yükseklik varsa WGS 84 referans elipsoidinin üzerindeki metre cinsinden döndürülür. Eğer bu konumun yüksekliği yoksa, 0.0 döndürülür.

Location.ReducedAccuracy özelliği yalnızca iOS tarafından kullanılır ve diğer tüm platformlarda false döndürür.