I am implementing a function to find my latitude and longitude but it keeps giving a null value. I declared android.permission.ACCESS_FINE_LOCATION, android.permission.ACCESS_BACKGROUND_LOCATION, android.permission.ACCESS_COARSE_LOCATION, and android.permission.INTERNET.
I granted all permissions and it shows a 'granted' toast but why my location is always null?
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var fusedLocationProviderClient : FusedLocationProviderClient
companion object {
private const val PERMISSION_REQUEST_ACCESS_LOCATION = 100
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
getCurrentLocation()
}
private fun getCurrentLocation() {
if( checkPermissions() )
{
if(isLocationEnabled())
{
if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
){
requestPermission()
return
}
fusedLocationProviderClient.lastLocation.addOnCompleteListener(this) { task ->
val location : Location? = task.result
if(location == null)
{
Toast.makeText(this, "Null Received", Toast.LENGTH_SHORT).show()
}
else
{
Toast.makeText(this, "Get Success", Toast.LENGTH_SHORT).show()
binding.txtLat.text = "" location.latitude
binding.txtLong.text = "" location.longitude
}
}
}
else
{
Toast.makeText(this, "Turn on location", Toast.LENGTH_SHORT).show()
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
}
else
{
//request permission here
requestPermission()
}
}
private fun isLocationEnabled() : Boolean {
val locationManager : LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
private fun requestPermission() {
ActivityCompat.requestPermissions(
this, arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_ACCESS_LOCATION
)
}
private fun checkPermissions() : Boolean
{
if(ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_COARSE_LOCATION)
==PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
return true
}
return false
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode == PERMISSION_REQUEST_ACCESS_LOCATION){
if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(applicationContext, "Granted", Toast.LENGTH_SHORT).show()
getCurrentLocation()
}
else {
Toast.makeText(applicationContext, "Denied", Toast.LENGTH_SHORT).show()
}
}
}
}
CodePudding user response:
As Google:
The getLastLocation() method returns a Task that you can use to get a Location object with the latitude and longitude coordinates of a geographic location. The location object may be null in the following situations:
Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache.
The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings.
Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted.
Solution:
1 Get last know location:
private Location getLastKnownLocation() {
List<String> providers = mLocationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = mLocationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null
|| l.getAccuracy() < bestLocation.getAccuracy()) {
Log.d("last known location: %s", l);
bestLocation = l;
}
}
if (bestLocation == null) {
return null;
}
return bestLocation;
}
2 Receiving Location Updates: To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates link
CodePudding user response:
Here I shared how I solved the error for anyone having same problem that I got.
So the reason was there was no cache for the location that it could not access to my last location. I solved this problem by adding this.
add the below in
if(location == null)
fusedLocationProviderClient.requestLocationUpdates( locationRequest, locationCallback, Looper.getMainLooper() )
Then, I received an error to initialize locationCallback. So I added this.
2) add the below in onCreate
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult ?: return
for (location in locationResult.locations){
}
}
}