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.
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 LocationManager
sistem, mengimplementasikan LocationListener
, dan memanggil requestLocationUpdates
on 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!
- 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.ConnectionCallbacks
dan GooglePlayServicesClient.OnConnectionFailedListener
antarmuka. 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 location
menjadi 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.LocationListener
antarmuka 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 onConnected
callback, atau Anda akan mendapatkan IllegalStateException
karena 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 onLocationChanged
tidak 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 onCreate
metode 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 locationEnabled
bendera dalam onConnected
metode 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.