I'm trying to get Location information using getLastKnownLocation but I often get null.
Here is what I do:
Turn OFF location in Settings
Run my app - getLastKnownLocation returns null - this is expected
Turn ON location in Settings
Run my app again - getLastKnownLocation returns null !?
Run Google Maps
Run my app again - getLastKnownLocation returns a valid Location !?
I found this question where the accepted answer suggests to launch Maps first in order to get the location:
FusedLocationApi.getLastLocation always null
The questions is: what is Google Maps doing to get the location? And how can I do the same in my code?
Thanks!
Thanks everyone for the help!
I was missing uses-features declarations in my manifest - thanks #CommonsWare for the link: https://developer.android.com/guide/topics/location/strategies.html#java
<!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature android:name="android.hardware.location.network" />
Also, requesting updates like this is needed as well:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
In my case the GPS provider needs a few minutes to connect and start sending data - the Network provider seems to be faster but does not always work - so I'll use both of them.
Update: a few key points
It's not really intuitive, but in order to get data from getLastKnownLocation some app on the device - be it Google Maps or our own app - needs to call requestLocationUpdates.
Some providers might not be enabled on a particular device - so it's a good idea to use both the GPS_PROVIDER and the NETWORK_PROVIDER - or use all enabled providers: locationManager.getProviders(true)
Here is the code I ended up using:
for ( String provider : locationManager.getProviders(true) ) {
setLocation( locationManager.getLastKnownLocation(provider) );
locationManager.requestLocationUpdates(provider, Tools.MIN_5, 0, locationListener);
}
// call setLocation again in locationListener.onLocationChanged
here is a code chunk which may help you.
if (!::mFusedLocationProviderClient.isInitialized) {
mFusedLocationProviderClient = FusedLocationProviderClient(mContext)
mLocationRequest = LocationRequest()
mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
mLocationRequest.interval = 10000
mLocationRequest.fastestInterval = 5000
mLocationRequest.smallestDisplacement = 1000 * 100f
}
if (ActivityCompat.checkSelfPermission(
AppName.appContext,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
AppName.appContext,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// not enough permission
return
}
mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, object : LocationCallback() {
override fun onLocationResult(p0: LocationResult?) {
super.onLocationResult(p0)
mFusedLocationProviderClient.removeLocationUpdates(this)
if (p0 != null) {
//here is your location
} else {
// location is null
}
}
override fun onLocationAvailability(p0: LocationAvailability?) {
if(p0?.isLocationAvailable!= true){
//location not available.
}
}
}, Looper.getMainLooper())
make sure you give all permission and if you run app above 6.1 device then handle permission..
after that used this code..
add below dependency into app level gradle file..
//Place API
implementation 'com.google.android.gms:play-services-places:16.0.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
define this into class level as global deceleration.
private lateinit var fusedLocationClient: FusedLocationProviderClient
private var context: Context? = null
private var locationCallback: LocationCallback? = null
private var locationRequest: LocationRequest? = null
private var googleApiClient: GoogleApiClient? = null
after that onCreate method..
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
make method for getting location..
fun getCurrentLocation() {
// Get Current location and do reverse geocoding
ProgressUtils.showOldProgressDialog(this)
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
ProgressUtils.closeOldProgressDialog()
for (location in locationResult.locations) {
// here you get current lat ,long,etc value..
stopLocationUpdates()
}
} catch (e: Exception) {
e.message.loggerError()
stopLocationUpdates()
}
}
}
}
locationRequest = LocationRequest().apply {
interval = 10000
fastestInterval = 5000
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
startLocationUpdates()
}
make location update..
fun startLocationUpdates() {
googleApiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.build()
googleApiClient!!.connect()
val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest!!)
builder.setAlwaysShow(true)
val result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
result.setResultCallback { result ->
val status = result.status
when (status.statusCode) {
LocationSettingsStatusCodes.SUCCESS -> {
Log.i(TAG, "All location settings are satisfied.")
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
}
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ")
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(this, LOCATION_SETTING_REQUEST_CODE)
} catch (e: IntentSender.SendIntentException) {
Log.i(TAG, "PendingIntent unable to execute request.")
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.")
}
}
}
make method for stop location..
private fun stopLocationUpdates() {
if (locationCallback != null) {
fusedLocationClient?.removeLocationUpdates(locationCallback)
}
}
override fun onStop() {
super.onStop()
stopLocationUpdates()
}
override fun onPause() {
super.onPause()
stopLocationUpdates()
}
if handle permission than permission is grant then call back getting onActivity Result method there put below code..
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
Related
After 2 days of struggle, I have been forced to ask this question. I have been searching StackOverflow but no solution seems to work for me. I don't know why.
I am trying to get the current device location once:
(a) the permissions have been granted
(b) user has enabled location service by tapping 'Okay' in the dialogue box that appears in the fragment (SelectLocationFragment.kt)
The issue: Once the permissions are granted, location is enabled by pressing 'okay' in the dialogue - If I use hard coded values like here:
//currentLatLng = LatLng(51.000, -0.0886)
instead of :
currentLatLng = LatLng(mCurrentLocation.latitude,mCurrentLocation.longitude)
It works fine. But this is not ideal of course. I'd like real time device location using onLocationCallBack's onLocationResult using:
fusedLocationClient.requestLocationUpdates(locationRequest,locationCallback, Looper.getMainLooper())
The problem is when I try to use:
currentLatLng = LatLng(mCurrentLocation.latitude,mCurrentLocation.longitude)
a) onLocationCallBack does not seem to be called. And therefore no call to onLocationResult happens, and therefore, mCurrentLocation remains uninitialised. And hence I get the error :
kotlin.UninitializedPropertyAccessException: lateinit property mCurrentLocation has not been initialized
This my onMapReady()
#SuppressLint("MissingPermission")
override fun onMapReady(gMap: GoogleMap) {
isPoiSelected = false
map = gMap
**checkPermissionsAndDeviceLocationSettings()**
setMapStyle(map)
setPoiClick(map)
setMapLongClick(map)
}
This is checkPermissionAndDeviceLocationSettings():
#SuppressLint("MissingPermission")
private fun checkPermissionsAndDeviceLocationSettings() {
if (isPermissionGranted()) {
checkDeviceLocationSettings()
} else {
requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_PERMISSION_LOCATION
)
}
}
This is checkDeviceLocationSettings:
private fun checkDeviceLocationSettings(resolve: Boolean = true) {
val locationRequest = LocationRequest.create().apply {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 10000L
}
val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
val settingsClient = LocationServices.getSettingsClient(requireActivity())
val locationSettingsResponseTask =
settingsClient.checkLocationSettings(builder.build())
locationSettingsResponseTask.addOnFailureListener { exception ->
if (exception is ResolvableApiException && resolve) {
try {
startIntentSenderForResult(
exception.resolution.intentSender,
REQUEST_TURN_DEVICE_LOCATION_ON, null, 0, 0, 0, null
)
} catch (sendEx: IntentSender.SendIntentException) {
Log.d(
SaveReminderFragment.TAG,
"Error getting location settings resolution: " + sendEx.message
)
}
} else {
Snackbar.make(
activity!!.findViewById<CoordinatorLayout>(R.id.myCoordinatorLayout),
R.string.location_required_error, Snackbar.LENGTH_INDEFINITE
).setAction(android.R.string.ok) {
checkDeviceLocationSettings()
}.show()
}
}
locationSettingsResponseTask.addOnSuccessListener {
Log.e(TAG, "SUCCESSFUL!")
Toast.makeText(requireContext(), "TOAST", Toast.LENGTH_SHORT).show()
enableLocation(locationRequest)
showSnackBar(getString(R.string.select_location))
}
}
This is enableLocation:
#SuppressLint("MissingPermission")
private fun enableLocation(locationRequest: LocationRequest) {
Log.e(TAG, "Inside Enable Location Start")
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
Log.e(TAG, "Inside on Location Result")
val locationList = locationResult.locations
Log.e(TAG, "${locationResult.locations}")
if(locationList.isNotEmpty()){
val location = locationList.last()
Log.i("MapsActivity", "Location: " + location.latitude + " " + location.longitude)
mCurrentLocation = location
}
fusedLocationClient.removeLocationUpdates(locationCallback)
}
}
map.isMyLocationEnabled = true
val locationResult: Task<Location> = fusedLocationClient.lastLocation
locationResult.addOnCompleteListener(OnCompleteListener<Location?> { task ->
if (task.isSuccessful) {
Log.e(TAG, locationResult.result?.latitude.toString())
// Set the map's camera position to the current location of the device.
if (task.result != null) {
mCurrentLocation = task.result!!
val latLng = LatLng(
mCurrentLocation.latitude,
mCurrentLocation.longitude
)
val update = CameraUpdateFactory.newLatLngZoom(
latLng,
18f
)
Toast.makeText(requireContext(), "CAMERA MOVING", Toast.LENGTH_SHORT).show()
map.animateCamera(update)
} else {
Log.e(TAG, " Task result is null")
//Need to do something here to get the real time location
fusedLocationClient.requestLocationUpdates(locationRequest,locationCallback, Looper.getMainLooper())
currentLatLng = LatLng(mCurrentLocation.latitude,mCurrentLocation.longitude)
//currentLatLng = LatLng(51.000, -0.0886)
val update = CameraUpdateFactory.newLatLngZoom(currentLatLng, 18f)
map.animateCamera(update)
}
} else {
Log.e(TAG, "Unsuccessful Task result")
Toast.makeText(requireContext(), "ENABLE LOCATION ELSE", Toast.LENGTH_LONG).show()
}
})
}
Is there any God sent man out there to help me resolve this issue. I am beginning to fade away.
If you guys need to see the entire file:
Thank you in advance.
FusedLocationProvider can return a null Location, especially the first time it fetches a Location. So, as you have found, simply returning when the result is null will force requestLocationUpdates() to fire again and actually fetch a valid Location the second time.
I think you can also force FusedLocationProvider to have a Location the first time if you just open the Google Maps app and wait for it to obtain a GPS lock. Of course, you wouldn't want your users to have to perform this process in order for your app to work, but it's still good to know for debugging.
The cause of this seems to be that FusedLocationProvider tries to return the most recently fetched Location for the device. If this Location is too old, has never been fetched, or the user toggled on/off the Location option on their phone, it just returns null.
i am trying to get user's location using only GPS provider. i don't want my app to get the last known location or request for location updates after a particular period of time or when location is changed.is there any way that can give me current location on button press ??? ... i am a beginner, i have tried LocationManager API from android studio and it returns network provided location fine but dosent work when using GPS . here is my code :
fun getlocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), locationPermissionCode)
}
else
{
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
// val listener = locationListener()
val gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
val network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
//if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N)
if (gps || network) {
if (network) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 5F, this)
}
if (gps) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 5F, this)
}
}
else {
val AlertDialog = AlertDialog.Builder(this)
AlertDialog.setTitle("GPS is Disabled")
AlertDialog.setMessage("Do you want enable GPS ?")
AlertDialog.setPositiveButton("Yes") { dialougeInterface: DialogInterface, i: Int ->
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
dialougeInterface.dismiss()
}
AlertDialog.setNegativeButton("No") { dialouge: DialogInterface, i: Int ->
dialouge.dismiss()
}
AlertDialog.show()
}
}
}
i have added location listener in the parent class " class AddCustomer : AppCompatActivity() , LocationListener "
in override function :
override fun onLocationChanged(location: Location) {
locationx.text = location.latitude.toString() +" , "+ location.longitude.toString()
}
should i use "getcurrentlocation()" method from "LocationManager" ?
I don't know if you are getting your last location or not. Here's the answer when you are not getting anything at all from the gps provider.
Making this block like this will only make you get your location via gps.
if (gps) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 5F, this)
}
The above can return when your device's GPS chipset feels like it's getting signal from the GPS, so when inside a building, it will likely be not getting any responds.
Go outside and try it out.
In your usecase, pressing a button to get an accurate location, in case the user can't receive any signal, you should provide a callback for timeout.
private val mHandler = Handler(Looper.getMainLooper())
private val mTimeoutRunnable = Runnable {
//stopLoading
//Toast the user to try it somewhere else
}
fun askGsp() {
mHandler.postDelayed(mTimeoutRunnable, 5 * 1000) //time out in 5 seconds
//ask for gps update like the code above
//...
override fun onLocationChanged(location: Location) {
mHandler.removeCallbacks(mTimeoutRunnable) //remove timeout action
locationx.text = location.latitude.toString() +" , "+
location.longitude.toString()
}
}
I'm using the FusedLocationProviderClient to access the lastLocation of the user. If it's null, I'm waiting for requestLocationUpdates to return.
I've tested this on my Pixel 3a by rebooting the device, which clears the last location, however it takes >2 mins to return a location.
Here's my code. What am I doing wrong?
private fun onLocationPermissionGranted() {
val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(
requireContext()
)
fusedLocationProviderClient.flushLocations()
Log.i("Jamie", "Attempting to access last location")
val locationRequest = LocationRequest.create()
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
locationRequest.interval = 5000
locationRequest.numUpdates = 1
val callback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
Log.i("Jamie", "Calling location permission granted again")
onLocationPermissionGranted()
}
}
fusedLocationProviderClient.lastLocation
.addOnSuccessListener { location: Location? ->
Log.i("Jamie", "FusedLocation onsuccess called")
if (location == null) {
Log.i("Jamie", "location null")
}
location?.let {
fusedLocationProviderClient.removeLocationUpdates(callback)
Log.i("Jamie", "Location received")
this.map.isMyLocationEnabled = true
viewModel.currentLocation = location
updateCamera(location.latitude, location.longitude)
}
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest, callback, Looper.getMainLooper())
}
2020-08-31 14:04:33.834 3780-3780/com.redacted I/Jamie: Attempting to access last location
2020-08-31 14:04:34.547 3780-3780/com.redacted I/Jamie: FusedLocation onsuccess called
2020-08-31 14:04:34.547 3780-3780/com.redacted I/Jamie: location null
2020-08-31 14:06:50.404 3780-3780/com.redacted I/Jamie: Calling location permission granted again
2020-08-31 14:06:50.404 3780-3780/com.redacted I/Jamie: Attempting to access last location
2020-08-31 14:06:50.517 3780-3780/com.redacted I/Jamie: FusedLocation onsuccess called
2020-08-31 14:06:50.517 3780-3780/com.redacted I/Jamie: Location received
I am trying to create a method that will get the last known location and assign that value to a global variable that I will use later. I am following this training.
In the end, this is the code that I've wrote:
public void getCurrentLocation() {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
fusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
mCurrentLocation = new Location(location);
System.out.println("In method getCurrentLocation: Latitude = " + location.getLatitude() + " Longitude = " + location.getLongitude());
System.out.println("In method getCurrentLocation for mCurrentLocation: Latitude = " + mCurrentLocation.getLatitude() + " Longitude = " + mCurrentLocation.getLongitude());
} else {
Toast.makeText(MainActivity.this, "Can't get the current location", Toast.LENGTH_SHORT).show();
}
}
});
}
The getCurrentLocation() method I will call in the onCreate() method of MainActivity and I can see the prints from the method so my variable got a location, but if I try to use the mCurrentLocation in some other context (for example I want to go to the last known location using this variable) the variable will be null. I am not sure that I need new Location(location), I added it because I thought that my variable will point to a null place in the memory after we exit the method, but it looks that it is not the case (I get the same outcome).
According to official documentation, Last Known Location could be Null in case of:
Location is turned off in the device settings. As it clears the
cache.
The device never recorded its location. (New device)
Google Play services on the device has restarted.
In this case, you should requestLocationUpdates and receive the new location on the LocationCallback.
By the following steps your last known Location never null.
Pre-requisite:
EasyPermission library
Step 1:
In manifest file add this permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Step 2:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Create location callback when it's ready.
createLocationCallback()
//createing location request, how mant request would be requested.
createLocationRequest()
//Build check request location setting request
buildLocationSettingsRequest()
//FusedLocationApiClient which includes location
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
//Location setting client
mSettingsClient = LocationServices.getSettingsClient(this)
//Check if you have ACCESS_FINE_LOCATION permission
if (!EasyPermissions.hasPermissions(
this#MainActivity,
Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermissionsRequired()
}
else{
//If you have the permission we should check location is opened or not
checkLocationIsTurnedOn()
}
}
Step 3:
Create required functions to be called in onCreate()
private fun requestPermissionsRequired() {
EasyPermissions.requestPermissions(
this,
getString(R.string.location_is_required_msg),
LOCATION_REQUEST,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
private fun createLocationCallback() {
//Here the location will be updated, when we could access the location we got result on this callback.
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
mCurrentLocation = locationResult.lastLocation
}
}
}
private fun buildLocationSettingsRequest() {
val builder = LocationSettingsRequest.Builder()
builder.addLocationRequest(mLocationRequest!!)
mLocationSettingsRequest = builder.build()
builder.setAlwaysShow(true)
}
private fun createLocationRequest() {
mLocationRequest = LocationRequest.create()
mLocationRequest!!.interval = 0
mLocationRequest!!.fastestInterval = 0
mLocationRequest!!.numUpdates = 1
mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
public fun checkLocationIsTurnedOn() { // Begin by checking if the device has the necessary location settings.
mSettingsClient!!.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this) {
Log.i(TAG, "All location settings are satisfied.")
startLocationUpdates()
}
.addOnFailureListener(this) { e ->
val statusCode = (e as ApiException).statusCode
when (statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
try {
val rae = e as ResolvableApiException
rae.startResolutionForResult(this#MainActivity, LOCATION_IS_OPENED_CODE)
} catch (sie: IntentSender.SendIntentException) {
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
mRequestingLocationUpdates = false
}
}
}
}
private fun startLocationUpdates() {
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest,
mLocationCallback, null
)
}
Step 4:
Handle callbacks in onActivityResult() after ensuring the location is opened or the user accepts to open it in.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
LOCATION_IS_OPENED_CODE -> {
if (resultCode == AppCompatActivity.RESULT_OK) {
Log.d(TAG, "Location result is OK")
} else {
activity?.finish()
}
}
}
Step 5:
Get last known location from FusedClientApi
override fun onMapReady(map: GoogleMap) {
mMap = map
mFusedLocationClient.lastLocation.addOnSuccessListener {
if(it!=null){
locateUserInMap(it)
}
}
}
private fun locateUserInMap(location: Location) {
showLocationSafetyInformation()
if(mMap!=null){
val currentLocation = LatLng(location.latitude,location.longitude )
addMarker(currentLocation)
}
}
private fun addMarker(currentLocation: LatLng) {
val cameraUpdate = CameraUpdateFactory.newLatLng(currentLocation)
mMap?.clear()
mMap?.addMarker(
MarkerOptions().position(currentLocation)
.title("Current Location")
)
mMap?.moveCamera(cameraUpdate)
mMap?.animateCamera(cameraUpdate)
mMap?.setMinZoomPreference(14.0f);
}
I hope this would help.
Happy Coding 🤓
A few weeks later I came up with some sort of a explanation to what is happening and how I managed to get the result that I want. I only had to do the first 3 steps that #MustafaKhaled wrote in his answer, this will make the mFusedLocationClient global variable to have its getLastLocation() method called (I think this happens because I request location updates, see #MustafaKhaled post).
Now, what we do with the last location? The response is nothing, because we do not handle what will happen if we successfully retrieve the location.
That being said, we will need to add what will happen onSuccess() with the location. In my case, I had to retain the value of the mCurrentLocation so I still need the method from the initial post to be implemented:
public void AddFusedLocationClientOnSuccessListener() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
mCurrentLocation = location;
}
}
});
}
Here I will be able to do some other things with the location if needed (for example if I want the application to animate to the current location), but later, if I when I use buttons or other graphical elements, I will be able to use the mCurrentLocation variable.
Now, I will be able to call the mCurrentLocation directly in the onCreate()? The answer is NO, because we will have to wait for mFusedLocationClient to successfully get the last known location, otherwise themCurrentLocation will be null, that is the reason in the initial post it did not work, we were not calling the getLastLocation() method until we will get success.
I hope this answer will be helpful for other peoples that encounter this problem and they don't fully understand what happens in the onCreate().
I want to return current user location when location is available.
this is my code:
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
if (locationResult.lastLocation != null && locationResult.lastLocation.latitude > 0 && locationResult.lastLocation.longitude > 0) {
lastLocation = locationResult.lastLocation
currentUserLatLng = LatLng(lastLocation.latitude, lastLocation.longitude)
fusedLocationClient.removeLocationUpdates(locationCallback)
}
}
}
the problem is, it's never called, I have the permission and allow my app to use gps, I set a debugger for it and it never comes in
could you help me? what is wrong with this code?
Why have you written locationResult.lastLocation.latitude > 0 & locationResult.lastLocation.longitude > 0 in your code? They can be negative
Did you call requestLocationUpdates somewhere?
fusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper());