Bagikan melalui


Geolokasi

Lihat sampel. Lihat sampel

Artikel ini menjelaskan cara menggunakan antarmuka .NET Multi-platform App UI (.NET MAUI). IGeolocation Antarmuka ini menyediakan API untuk mengambil koordinat geolokasi perangkat saat ini.

Implementasi default antarmuka IGeolocation tersedia melalui properti Geolocation.Default. Antarmuka IGeolocation dan kelas Geolocation terkandung dalam namespace Microsoft.Maui.Devices.Sensors.

Mulai sekarang!

Untuk mengakses fungsionalitas Geolokasi , pengaturan khusus platform berikut diperlukan:

Izin lokasi kasar atau halus, atau keduanya, harus ditentukan dan dikonfigurasi dalam proyek Android.

Selain itu, jika aplikasi Anda menargetkan Android 5.0 (API level 21) atau yang lebih tinggi, Anda harus menyatakan bahwa aplikasi Anda menggunakan fitur perangkat keras dalam file manifes. Ini dapat ditambahkan dengan cara berikut:

  • Tambahkan izin berbasis rakitan:

    Buka file Platforms/Android/MainApplication.cs dan tambahkan atribut assembly berikut setelah arahan 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)]
    

    Jika aplikasi Anda menargetkan Android 10 - Q (API Level 29 atau lebih tinggi) dan meminta LocationAlways, Anda juga harus menambahkan permintaan izin ini:

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

    - atau -

  • Perbarui Manifes Android:

    Buka file Platforms/Android/AndroidManifest.xml dan tambahkan yang berikut ini di simpul 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" />
    

    Jika aplikasi Anda menargetkan Android 10 - Q (API Level 29 atau lebih tinggi) dan meminta LocationAlways, Anda juga harus menambahkan permintaan izin ini:

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

    - atau -

  • Perbarui Manifes di Android menggunakan editor manifes:

    Di Visual Studio klik dua kali pada file Platforms/Android/AndroidManifest.xml untuk membuka editor manifes Android. Kemudian, di bawah Izin yang diperlukan , periksa izin yang tercantum di atas. Ini akan secara otomatis memperbarui file AndroidManifest.xml.

Petunjuk / Saran

Pastikan untuk membaca dokumentasi Android tentang pembaruan lokasi latar belakang, karena ada banyak batasan yang perlu dipertimbangkan.

Dapatkan lokasi terakhir yang diketahui

Perangkat mungkin telah menyimpan cache lokasi perangkat terbaru. GetLastKnownLocationAsync() Gunakan metode untuk mengakses lokasi yang di-cache, jika tersedia. Ini sering lebih cepat daripada melakukan kueri lokasi lengkap, tetapi bisa kurang akurat. Jika tidak ada lokasi cache, metode ini mengembalikan null.

Nota

Jika perlu, API Geolokasi meminta izin kepada pengguna.

Contoh kode berikut menunjukkan pemeriksaan lokasi yang di-cache:

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

Bergantung pada perangkat, tidak semua nilai lokasi mungkin tersedia. Misalnya, properti Altitude dapat berupa null, memiliki nilai 0, atau memiliki nilai positif yang menunjukkan meter di atas permukaan laut. Nilai lain yang mungkin tidak ada termasuk properti Speed dan Course.

Dapatkan lokasi saat ini

Saat memeriksa lokasi perangkat terakhir yang diketahui mungkin lebih cepat, namun kemungkinan tidak akurat. GetLocationAsync Gunakan metode untuk mengkueri perangkat untuk lokasi saat ini. Anda dapat mengonfigurasi akurasi dan batas waktu kueri. Metode yang menerapkan overload dengan parameter GeolocationRequest dan CancellationToken adalah pilihan terbaik, karena bisa jadi perlu waktu untuk mendapatkan lokasi perangkat.

Nota

Jika perlu, API Geolokasi meminta izin kepada pengguna.

Contoh kode berikut menunjukkan cara meminta lokasi perangkat, sambil mendukung pembatalan:

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

Tidak semua nilai lokasi mungkin tersedia, tergantung pada perangkat. Misalnya, properti Altitude dapat berupa null, memiliki nilai 0, atau memiliki nilai positif yang menunjukkan meter di atas permukaan laut. Nilai lain yang mungkin tidak ada termasuk Speed dan Course.

Peringatan

GetLocationAsync dapat mengembalikan null dalam beberapa skenario. Ini menunjukkan bahwa platform dasar tidak dapat memperoleh lokasi terkini.

Pantau perubahan lokasi

Selain mengkueri perangkat untuk lokasi saat ini, Anda dapat mendengarkan perubahan lokasi saat aplikasi berada di latar depan.

Untuk memeriksa apakah aplikasi saat ini memantau perubahan lokasi, ada properti yang dapat Anda query IsListeningForeground. Setelah Anda siap untuk mulai mendengarkan perubahan lokasi, Anda harus memanggil metode StartListeningForegroundAsync. Metode ini mulai mendengarkan pembaruan lokasi dan menaikkan LocationChanged peristiwa saat lokasi berubah, asalkan aplikasi berada di latar depan. Objek GeolocationLocationChangedEventArgs yang menyertai peristiwa ini memiliki Location properti, jenis Location, yang mewakili lokasi baru yang telah terdeteksi.

Nota

Jika perlu, API Geolokasi meminta izin kepada pengguna.

Contoh kode berikut menunjukkan cara mendengarkan perubahan lokasi, dan cara memproses lokasi yang diubah:

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
}

Penanganan kesalahan dapat diimplementasikan dengan mendaftarkan penanganan aktivitas untuk peristiwa tersebut ListeningFailed . Objek GeolocationListeningFailedEventArgs yang menyertai peristiwa ini memiliki properti Error dengan tipe GeolocationError, yang menunjukkan alasan mengapa proses pendengaran gagal. Ketika acara ListeningFailed terjadi, pemantauan perubahan lokasi lebih lanjut berhenti dan tidak ada acara LocationChanged lebih lanjut yang dimunculkan.

Untuk berhenti mendengarkan perubahan lokasi, panggil metode 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
    }
}

Nota

Metode StopListeningForeground ini tidak berpengaruh ketika aplikasi tidak mendengarkan perubahan lokasi.

Periksa apakah layanan lokasi diaktifkan

Kelas Geolocation memiliki properti baca-saja IsEnabled yang dapat digunakan untuk menentukan apakah layanan lokasi telah diaktifkan pada perangkat.

Akurasi

Bagian berikut menguraikan jarak akurasi lokasi, per platform:

Penting

iOS memiliki beberapa batasan mengenai akurasi. Untuk informasi selengkapnya, lihat bagian Perbedaan platform .

Terendah

Plattform Jarak (dalam meter)
Android 500
Ios 3000
Windows 1000 - 5000

Kurang Penting

Plattform Jarak (dalam meter)
Android 500
Ios 1000
Windows 300 - 3000

Sedang (Default)

Plattform Jarak (dalam meter)
Android 100 - 500
Ios 100
Windows 30-500

Tinggi

Plattform Jarak (dalam meter)
Android 0 - 100
Ios 10
Windows <= 10

Terbaik

Plattform Jarak (dalam meter)
Android 0 - 100
Ios ~0
Windows <= 10

Mendeteksi lokasi tiruan

Beberapa perangkat dapat mengembalikan lokasi tiruan dari penyedia atau oleh aplikasi yang menyediakan lokasi tiruan. Anda dapat mendeteksinya dengan menggunakan IsFromMockProvider pada setiap Location.

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

Jarak antara dua lokasi

Metode ini CalculateDistance menghitung jarak antara dua lokasi geografis. Jarak terhitung ini tidak memperhitungkan jalan atau jalur lain, dan hanya jarak terpendek antara dua titik di sepanjang permukaan Bumi. Perhitungan ini dikenal sebagai perhitungan jarak lingkaran besar .

Kode berikut menghitung jarak antara amerika serikat kota Boston dan San Francisco:

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

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

Konstruktor Location(Double, Double, Double) menerima argumen garis lintang dan bujur, masing-masing. Nilai garis lintang positif berada di utara khatulistiwa, dan nilai bujur positif berada di timur Prime Meridian. Gunakan argumen akhir untuk CalculateDistance menentukan mil atau kilometer. Kelas ini UnitConverters juga mendefinisikan metode KilometersToMiles dan MilesToKilometers untuk mengonversi antara dua unit.

Platform yang Berbeda

Bagian ini menjelaskan perbedaan khusus platform dengan API geolokasi.

Ketinggian dihitung secara berbeda pada setiap platform.

Di Android, ketinggian, jika tersedia, dikembalikan dalam meter di atas elipsoid referensi WGS 84. Jika lokasi ini tidak memiliki ketinggian, 0.0 dikembalikan.

Properti Location.ReducedAccuracy hanya digunakan oleh iOS dan dikembalikan false di semua platform lain.