Android: LocationManager vs Google Play Services

151

Saya ingin membangun aplikasi yang berpusat pada mendapatkan lokasi pengguna saat ini dan kemudian menemukan tempat menarik (seperti bar, restoran, dll) yang dekat dengannya melalui Google Places API .

Setelah mencari tempat untuk memulai di web, saya menemukan beberapa tutorial yang menggunakan LocationManagerkelas dan beberapa lainnya yang menggunakan Layanan Google Play untuk menemukan lokasi pengguna.

Pada pandangan pertama mereka berdua melakukan hal yang sama, tetapi karena saya baru dalam hal ini, saya jadi sedikit bingung dan saya tidak tahu metode mana yang paling sesuai dengan kebutuhan saya. Jadi, saya ingin bertanya:

Apa perbedaan antara kedua metode ini untuk menemukan lokasi (jika ada)?

SoCo
sumber
1
kunjungi di sini stackoverflow.com/questions/21397177/…
Mohammad Tauqir

Jawaban:

319

Lokasi Pengguna di Android

Mendapatkan lokasi pengguna di Android sedikit lebih mudah daripada di iOS. Untuk memulai kebingungan, ada dua cara yang sangat berbeda untuk melakukannya. Yang pertama menggunakan Android API dari android.location.LocationListener, dan yang kedua menggunakan Google Play Services APIs com.google.android.gms.location.LocationListener. Mari kita pergi melalui keduanya.

  1. API Lokasi Android

    API lokasi Android menggunakan tiga penyedia berbeda untuk mendapatkan lokasi -

    • LocationManager.GPS_PROVIDER- Penyedia ini menentukan lokasi menggunakan satelit. Tergantung pada kondisinya, penyedia ini mungkin perlu waktu untuk mengembalikan perbaikan lokasi.
    • LocationManager.NETWORK_PROVIDER- Penyedia ini menentukan lokasi berdasarkan ketersediaan menara seluler dan titik akses WiFi. Hasil diambil melalui pencarian jaringan.
    • LocationManager.PASSIVE_PROVIDER- Penyedia ini akan mengembalikan lokasi yang dihasilkan oleh penyedia lain. Anda secara pasif menerima pembaruan lokasi ketika aplikasi atau layanan lain memintanya tanpa benar-benar meminta lokasi itu sendiri.

Intinya adalah Anda mendapatkan objek dari LocationManagersistem, mengimplementasikan LocationListener, dan memanggil requestLocationUpdateson LocationManager.

Berikut cuplikan kode:

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      // Called when a new location is found by the network location provider.
      makeUseOfNewLocation(location);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}
  };

// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Panduan API Google tentang Strategi Lokasimenjelaskan kode dengan cukup baik. Tetapi mereka juga menyebutkan bahwa dalam kebanyakan kasus, Anda akan mendapatkan kinerja baterai yang lebih baik, serta akurasi yang lebih tepat, dengan menggunakan API Layanan Lokasi Google sebagai gantinya. Sekarang kebingungan dimulai!

  1. API Layanan Lokasi Google

API Layanan Lokasi Google adalah bagian dari APK Layanan Google Play ( inilah cara mengaturnya ). Mereka dibangun di atas API Android. API ini menyediakan "Penyedia Lokasi Yang Menyatu" alih-alih penyedia yang disebutkan di atas. Penyedia ini secara otomatis memilih penyedia yang mendasarinya untuk digunakan, berdasarkan keakuratan, penggunaan baterai, dll. Cepat karena Anda mendapatkan lokasi dari layanan seluruh sistem yang terus memperbaruinya. Dan Anda dapat menggunakan fitur yang lebih canggih seperti geofencing.

Untuk menggunakan Layanan Lokasi Google, aplikasi Anda perlu terhubung ke GooglePlayServicesClient. Untuk terhubung ke klien, aktivitas Anda (atau fragmen, atau lebih) perlu diimplementasikan GooglePlayServicesClient.ConnectionCallbacksdan GooglePlayServicesClient.OnConnectionFailedListenerantarmuka. Berikut ini contoh kode:

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        locationClient = new LocationClient(this, this, this);
    }

    @Override
    public void onConnected(Bundle bundle) {
    Location location = locationClient.getLastLocation() ;
        Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDisconnected() {
    Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // code to handle failed connection
        // this code can be found here — http://developer.android.com/training/location/retrieve-current.html 
    }
  • Kenapa locationClient.getLastLocation()null?

The locationClient.getLastLocation()mendapat lokasi terakhir yang diketahui dari klien. Namun, Penyedia Lokasi Fusi hanya akan mempertahankan lokasi latar belakang jika setidaknya satu klien terhubung dengannya. Setelah klien pertama terhubung, ia akan segera mencoba untuk mendapatkan lokasi. Jika aktivitas Anda adalah klien pertama untuk menghubungkan dan Anda menelepon getLastLocation()langsung di onConnected(), yang mungkin tidak cukup waktu untuk lokasi pertama yang masuk. Hal ini akan mengakibatkan locationmenjadi null.

Untuk mengatasi masalah ini, Anda harus menunggu (tidak pasti) sampai penyedia mendapatkan lokasi dan kemudian menelepon getLastLocation(), yang tidak mungkin diketahui. Opsi lain (lebih baik) adalah mengimplementasikan com.google.android.gms.location.LocationListenerantarmuka untuk menerima pembaruan lokasi berkala (dan matikan begitu Anda mendapatkan pembaruan pertama).

    public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
    // . . . . . . . . more stuff here 
    LocationRequest locationRequest;
    LocationClient locationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // . . . . other initialization code
        locationClient = new LocationClient(this, this, this);
    locationRequest = new LocationRequest();
    // Use high accuracy
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
    locationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    }
    // . . . . . . . . other methods 
    @Override
    public void onConnected(Bundle bundle) {
        Location location = locationClient.getLastLocation();
        if (location == null)
            locationClient.requestLocationUpdates(locationRequest, this);
        else
            Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
    }
    // . . . . . . . . other methods
    @Override
    public void onLocationChanged(Location location) {
        locationClient.removeLocationUpdates(this);
        // Use the location here!!!
    }

Dalam kode ini, Anda memeriksa apakah klien sudah memiliki lokasi terakhir (dalam onConnected). Jika tidak, Anda meminta pembaruan lokasi, dan mematikan permintaan (dalam onLocationChanged()panggilan balik) segera setelah Anda mendapatkan pembaruan.

Perhatikan bahwa locationClient.requestLocationUpdates(locationRequest, this);harus ada di dalam onConnectedcallback, atau Anda akan mendapatkan IllegalStateExceptionkarena Anda akan mencoba untuk meminta lokasi tanpa terhubung ke Klien Layanan Google Play.

  • Pengguna telah menonaktifkan Layanan Lokasi

Sering kali, pengguna akan menonaktifkan layanan lokasi (untuk menghemat baterai, atau alasan privasi). Dalam kasus seperti itu, kode di atas masih akan meminta pembaruan lokasi, tetapi onLocationChangedtidak akan pernah dipanggil. Anda dapat menghentikan permintaan dengan memeriksa apakah pengguna telah menonaktifkan layanan lokasi.

Jika aplikasi Anda mengharuskan mereka untuk mengaktifkan layanan lokasi, Anda ingin menampilkan pesan atau bersulang. Sayangnya, tidak ada cara untuk memeriksa apakah pengguna telah menonaktifkan layanan lokasi di API Layanan Lokasi Google. Untuk ini, Anda harus kembali ke API Android.

Dalam onCreatemetode Anda :

    LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
    locationEnabled = false;
    Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;

Dan gunakan locationEnabledbendera dalam onConnectedmetode Anda seperti ini:

    if (location != null) {
    Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
    locationClient.requestLocationUpdates(locationRequest, this);
}

MEMPERBARUI

Dokumen diperbarui, LocationClient dihapus dan api mendukung untuk mengaktifkan GPS dengan satu klik dari dialog:

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

Tautan https://developer.android.com/training/location/change-location-settings#prompt

Klien lokasi baru: FusedLocationProviderClient

  private FusedLocationProviderClient fusedLocationClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}

Dianjurkan untuk pergi melalui https://developer.android.com/training/location sebelum melakukan tugas-tugas lokasi.

pRaNaY
sumber
9
Anda dapat menggunakan SettingsApi.checkLocationSettings()untuk memeriksa apakah pengguna telah mengaktifkan Layanan Lokasi (lihat di sini: developers.google.com/android/reference/com/google/android/gms/… ).
kaolick
3
LocationClient tidak ada lagi. Untuk panduan yang diperbarui dan jelas untuk Lokasi, silakan periksa artikel ini: blog.teamtreehouse.com/beginners-guide-location-android
lm2a
1
Dan halaman pelatihan dengan contoh SettingsApi: developer.android.com/training/location/…
androidguy
2
Anda juga dapat membuat pagar geo menggunakan LocationManager! Apakah api lokasi berfusi bekerja pada perangkat yang tidak memiliki layanan google play?
Muhammad Babar
Ini bisa menjadi cara lain yang lebih baik untuk memeriksa status aktifkan / nonaktifkan GPS fun isLocationEnabled(context: Context): Boolean { val locationMode: Int try { locationMode = Settings.Secure.getInt( context.contentResolver, Settings.Secure.LOCATION_MODE ) } catch (e: SettingNotFoundException) { e.printStackTrace() return false } return locationMode != Settings.Secure.LOCATION_MODE_OFF }
Wahib Ul Haq
32

Dalam pengalaman saya, "akurasi lebih tepat" tidak berarti lebih baik dengan cara apa pun. Kecuali saya kehilangan sesuatu, jika Anda ingin memastikan GPS digunakan, LocationManager adalah satu-satunya cara untuk pergi. Kami melacak kendaraan dengan aplikasi kami dan, sekali lagi, kecuali saya kehilangan sesuatu, Layanan Google Play menyediakan beberapa lokasi yang sangat tidak akurat.

Kit
sumber
2
Ya, dari pengalaman saya Layanan Google Play beberapa kali memberikan lokasi yang tidak akurat.
VY
2
Ya, API Layanan Lokasi Layanan Google Play dapat memberikan informasi Lokasi yang sangat menyesatkan. Modem WiFi dapat dipindahkan, modem WiFi diperbarui dengan informasi lokasi yang salah (yaitu jika lokasi dipalsukan oleh perangkat Android yang memperbarui lokasi modem WiFi) dan ada sejumlah keadaan lain yang dapat mengakibatkan data Lokasi salah dari triangulasi modem WiFi. Di semua aplikasi kami di mana Lokasi akurat wajib, kami hanya menggunakan GPS.
user1608385
27

Anda harus menggunakan api lokasi Layanan Google Play alih-alih LocationManager. Menurut dokumen:

API lokasi layanan Google Play lebih disukai daripada API lokasi kerangka kerja Android (android.location) sebagai cara menambahkan kesadaran lokasi ke aplikasi Anda. Jika saat ini Anda menggunakan API lokasi kerangka kerja Android, Anda sangat dianjurkan untuk segera beralih ke API lokasi layanan Google Play.

Mengenai alasan beralih, Google mengatakan ini:

API Layanan Lokasi Google, bagian dari Layanan Google Play, menyediakan kerangka kerja tingkat tinggi yang lebih kuat yang secara otomatis menangani penyedia lokasi, pergerakan pengguna, dan akurasi lokasi. Ini juga menangani penjadwalan pembaruan lokasi berdasarkan parameter konsumsi daya yang Anda berikan. Dalam kebanyakan kasus, Anda akan mendapatkan kinerja baterai yang lebih baik, serta akurasi yang lebih tepat, dengan menggunakan API Layanan Lokasi.

NoChinDeluxe
sumber
2
Apakah Anda memiliki tautan ke dokumentasi tempat kutipan ini berasal? Akan menarik untuk melihat apakah Google mengatakan sesuatu yang berbeda sekarang.
Edward Brey
3
Tentu saja mereka mengatakan ini, karena mereka menginginkan data lokasi Anda!
Flyview
Saat Anda menambahkan layanan Google play ke aplikasi Anda, jika pengguna menginstal aplikasi Anda, ia akan diminta untuk "memperbarui" layanan google play untuk menggunakan aplikasi Anda. Jika ponselnya hampir penuh (dengan meme whatsapp dan yang lainnya) atau pengguna tidak memiliki data, maaf untuk Anda teman saya
Dr Deo
2
@Fviewview Yap! Lol, cara mereka mengucapkannya membuatnya terdengar seperti solusi ajaib! Kelemahan terbesar adalah Anda membutuhkan Layanan Google Play di perangkat !!!
varun
25

Saya telah menggunakan API Layanan Lokasi Google cukup lama. Itu memang memiliki keuntungan, karena merangkum kompleksitas memiliki beberapa sumber untuk menentukan posisi. Namun itu merangkum terlalu banyak , sehingga ketika Anda mendapatkan posisi aneh, Anda tidak memiliki cara untuk menentukan dari mana posisi aneh itu berasal.

Dalam kehidupan nyata, saya memiliki beberapa nilai aneh yang muncul, karena berjarak 10 km dari posisi sebenarnya. Satu-satunya penjelasan adalah bahwa lokasi gila ini berasal dari kesalahan dalam Googles Wi-Fi atau database NWK - kesalahan yang akan selalu ada, karena topologi Wi-Fi dan Jaringan berubah setiap hari. Namun sayangnya (dan yang mengejutkan) API tidak memberi Anda informasi tentang bagaimana posisi individu diturunkan.

masukkan deskripsi gambar di sini

Ini membuat Anda memiliki masalah karena harus menyaring nilai-nilai aneh berdasarkan pemeriksaan masuk akal pada kecepatan, akselerasi, bearing, dll.

... atau kembali ke kerangka API lama yang baik dan gunakan GPS saja, itulah yang saya putuskan untuk lakukan sampai Google meningkatkan API yang menyatu.

j3App
sumber
7

API Layanan Lokasi Google , bagian dari Layanan Google Play, menyediakan kerangka kerja tingkat tinggi yang lebih kuat yang secara otomatis menangani penyedia lokasi , pergerakan pengguna , dan akurasi lokasi . Ini juga menangani penjadwalan pembaruan lokasi berdasarkan parameter konsumsi daya yang Anda berikan. Dalam kebanyakan kasus, Anda akan mendapatkan kinerja baterai yang lebih baik , serta akurasi yang lebih tepat, dengan menggunakan API Layanan Lokasi.

Perbedaan yang lebih mendetail antara kedua apis Google Play Service Location API dan Android Framework Location API dapat ditemukan di sini

Dhruvam Gupta
sumber
Saya menggunakan jawaban Anda untuk menjawab pertanyaan saya sendiri jika itu tidak masalah. Terima kasih banyak! stackoverflow.com/questions/39852955/…
Leniaal
@Leniaal, jadi tidakkah menurut Anda jawaban saya layak mendapat dukungan?
Dhruvam Gupta
Itu dokumen lama 3 tahun. Tapi ini plus 1
Drew
5

Ya, API Layanan Lokasi Layanan Google Play dapat memberikan informasi Lokasi yang sangat menyesatkan. Modem WiFi dapat dipindahkan, modem WiFi diperbarui dengan informasi lokasi yang salah (yaitu jika lokasi dipalsukan oleh perangkat Android yang memperbarui lokasi modem WiFi) dan ada sejumlah keadaan lain yang dapat mengakibatkan data Lokasi salah dari triangulasi modem WiFi. Di semua aplikasi kami di mana Lokasi akurat wajib, kami hanya menggunakan GPS.

pengguna1608385
sumber
4

Perbedaan antara kedua apis Google Play Service Location API dan Android Framework Location API berdasarkan pada layanan GPS

FusedLocationProviderClient

  1. Untuk pengambilan pertama, lokasi tidak boleh nol (yaitu: Beberapa aplikasi lain perlu memperbarui lokasi Terakhir di dalam database GoogleplayService. Jika itu nol, perlu diperbaiki)
  2. Untuk Ambil berurutan berikutnya, ia menggunakan requestLocationUpdates()metode untuk mengambil lokasi.
  3. Pengambilan lokasi hanya berdasarkan locationRequest.setInterval(milliseconds)dan setFastestInterval(milliseconds), bukan berdasarkan perubahan lokasi pengguna
  4. Nilai LatLng yang dikembalikan hanya mengandung 7 nilai desimal (mis: 11.9557996, 79.8234599), tidak seakurat
  5. Disarankan, ketika persyaratan aplikasi Anda mengambil jarak lokasi saat ini dapat diabaikan (akurasi 50 - 100 meter)
  6. Efektif dalam penggunaan baterai.

LocationManager Api

  1. Ambil lokasi pengguna dipanggil menggunakan locationManager.requestLocationUpdates ()
  2. Lokasi pengambilan berdasarkan perubahan lokasi pengguna dan interval waktu locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)

  3. Nilai LatLng yang dikembalikan telah mengandung 14 nilai desimal (mis: 11.94574594963342 79.81166719458997) nilai lokasi yang akurat

  4. Direkomendasikan untuk aplikasi berbasis lokasi, saat membutuhkan akurasi lebih banyak bahkan dalam meter.
  5. Penggunaan baterai didasarkan pada interval pengambilan dan jarak pengambilan.
Sackurise
sumber
Hei! 1 ° paling banyak 111_111 meter (20_299_280 / 180). Jadi, 0,0000001 ° adalah 0,011m = 1 cm. Saya tidak tahu di mana Anda membutuhkan resolusi GPS yang lebih baik. Dan saya bahkan tidak tahu, bagaimana Anda bisa mencapai resolusi GPS yang lebih baik.
babay