User location not showing on Button Click - android

I want to get the user location on button click. But it does not provide me location. I want to get user location by using android gps not with google play services
class NewPostActivity : AppCompatActivity(), LocationListener {
private val locationMangaer: LocationManager?
get() {
return getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
override fun onCreate(savedInstanceState: Bundle?) {
getLocationbtn.setOnClickListener {
locationMangaer!!.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10.toFloat(), this)
}
}
override fun onLocationChanged(location: Location?) {
Log.e("data", "called")
Log.e("data", "Location is ${location!!.latitude} and ${location.latitude}")
}
}

it is all of get current location code
class MainActivity : AppCompatActivity() {
val PERMISSION_ID = 42
lateinit var mFusedLocationClient: FusedLocationProviderClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
getLastLocation()
}
#SuppressLint("MissingPermission")
private fun getLastLocation() {
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
var location: Location? = task.result
if (location == null) {
requestNewLocationData()
} else {
findViewById<TextView>(R.id.latTextView).text = location.latitude.toString()
findViewById<TextView>(R.id.lonTextView).text = location.longitude.toString()
}
}
} else {
Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show()
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
} else {
requestPermissions()
}
}
#SuppressLint("MissingPermission")
private fun requestNewLocationData() {
var mLocationRequest = LocationRequest()
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationRequest.interval = 0
mLocationRequest.fastestInterval = 0
mLocationRequest.numUpdates = 1
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest, mLocationCallback,
Looper.myLooper()
)
}
private val mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
var mLastLocation: Location = locationResult.lastLocation
findViewById<TextView>(R.id.latTextView).text = mLastLocation.latitude.toString()
findViewById<TextView>(R.id.lonTextView).text = mLastLocation.longitude.toString()
}
}
private fun isLocationEnabled(): Boolean {
var locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
LocationManager.NETWORK_PROVIDER
)
}
private fun checkPermissions(): Boolean {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
return true
}
return false
}
private fun requestPermissions() {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_ID
)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == PERMISSION_ID) {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
getLastLocation()
}
}
}
}
you have to add this to your ``` manifest.xml``
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
and this to your gradle
implementation 'com.google.android.gms:play-services-location:17.0.0'
I hope it will help you . happy code

Related

How can i make a class that gives me the location. I tryed but always getting errors

So, im just trying to make a service that returns me the current location in android.
I've done all the work i think, but this is saying me that the system services are not available before onCreate()
Location Service :
class LocationService(context: Context): AppCompatActivity() {
companion object {
private const val PERMISSION_REQUEST_ACCESS_LOCATION = 100
}
private val context_activity: Context = context
private var fusedLocationProviderClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context_activity)
private var longitude: Double = 0.0
private var latitude: Double = 0.0
fun getLocation(): Array<Double> {
if (checkPermissions()) {
if (isLocationEnabled()) {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestPermission()
}
this.fusedLocationProviderClient.lastLocation.addOnCompleteListener(context_activity as Activity) { task ->
val location: Location? = task.result
if (location == null) {
Toast.makeText(context_activity, "Null received", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(
context_activity,
"Got Location Sucessfull",
Toast.LENGTH_SHORT
).show()
latitude = location.latitude
longitude = location.longitude
}
}
} else {
//settings open here
Toast.makeText(context_activity, "Turn on Location", Toast.LENGTH_SHORT).show()
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
} else {
//request permission here
requestPermission()
}
return arrayOf(longitude, latitude)
}
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(context_activity, "Granted", Toast.LENGTH_SHORT).show()
}else
{
Toast.makeText(context_activity, "Denied", Toast.LENGTH_SHORT).show()
}
}
}
private fun isLocationEnabled(): Boolean{
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
private fun checkPermissions(): Boolean {
return ActivityCompat.checkSelfPermission(context_activity, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context_activity, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
private fun requestPermission(){
ActivityCompat.requestPermissions(context_activity as Activity, arrayOf(android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_ACCESS_LOCATION)
}
}
Main activity:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//View Binding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
var arrayD = arrayOf(LocationService(this).getLocation())
binding.tvLat.text = arrayD.get(0).toString()
binding.tvLong.text = arrayD.get(1).toString()
}
}
And please tell me , if there is any better way to get the location from the device.
I have an APP, and currently im getting some bad results, like my position beeing shown far away from where i am. Talking about KM's

Android Kotlin - Unable to set location. Location remains at 0.0, 0.0

I am trying to set the location's latitude and longitude so I can use an API to get weather info.
When I run the app, I don't get any errors, but the location is 0.0, 0.0. A default location shows within the app.
I have made sure I'm checking/asking for location permission too.
This is code in Kotlin. I have implemented 'com.google.android.gms:play-services-location:17.1.0, added kotlin-android-extensions in the gradle, and added coarse, fine location permissions and internet permissions.
This is my location part of the MainActivity.kt
#SuppressLint("MissingPermission")
private fun getLastLocation() {
if(CheckPermission()){
if(isLocationEnabled()){
fusedLocationProviderClient.lastLocation.addOnCompleteListener{task ->
var location = task.result
if(location == null){
getNewLocation()
}else {
locationResult = location
}
}
}else{
Toast.makeText(this, "Location service not enabled", Toast.LENGTH_SHORT).show()
}
}else{
RequestPermission()
}
}
private fun CheckPermission() : Boolean {
if( (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ){
return true
}
return false
}
private fun RequestPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
), PERMISSION_ID
)
}
private fun isLocationEnabled() : Boolean{
var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_ID){
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "Permission granted")
}
}
}
#SuppressLint("MissingPermission")
private fun getNewLocation(){
locationRequest = LocationRequest()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 0
locationRequest.fastestInterval = 0
locationRequest.numUpdates = 2
fusedLocationProviderClient!!.requestLocationUpdates(
locationRequest, locationCallback, null
)
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(p0: LocationResult?){
var lastLocation = p0?.lastLocation
if (lastLocation != null) {
locationResult = lastLocation
}
}
}
MainActivity.kt -- FULL
package <censored>.weatherapp
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject
import java.lang.Exception
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity() {
companion object {
val API : String = "<censored>"
private var PERMISSION_ID : Int = 1000
val TAG = "MainActivity"
}
lateinit var fusedLocationProviderClient: FusedLocationProviderClient
lateinit var locationRequest : LocationRequest
lateinit var locationResult : Location
var latitude : Double = 0.0
var longitude : Double = 0.0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
getLastLocation()
weatherTask().execute()
}
inner class weatherTask() : AsyncTask<String, Void, String>() {
override fun onPreExecute() {
super.onPreExecute()
//Showing the ProgressBar, making the main design gone
findViewById<ProgressBar>(R.id.loader).visibility = View.VISIBLE
findViewById<RelativeLayout>(R.id.mainContainer).visibility = View.GONE
}
override fun doInBackground(vararg params: String?): String? {
latitude = locationResult.latitude
longitude = locationResult.longitude
Log.d(TAG, "$latitude , $longitude")
var response : String?
try{
response = URL("https://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&units=metric&appid=$API")
.readText(Charsets.UTF_8)
}catch (e: Exception){
response = null
}
return response
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
try {
// Extracting JSON returns from the API
val jsonObj = JSONObject(result)
val main = jsonObj.getJSONObject("main")
val sys = jsonObj.getJSONObject("sys")
val wind = jsonObj.getJSONObject("wind")
val weather = jsonObj.getJSONArray("weather").getJSONObject(0)
val updatedAt:Long = jsonObj.getLong("dt")
val updatedAtText = "Updated at: "+ SimpleDateFormat("dd/MM/yyyy H:mm ", Locale.ENGLISH).format(Date(updatedAt*1000))
val temp = main.getDouble("temp").toInt().toString()
val tempMin = main.getDouble("temp_min").toInt().toString()
val tempMax = main.getDouble("temp_max").toInt().toString()
val tempText = "$temp°C"
val tempMinText = "Min Temp: $tempMin°C"
val tempMaxText = "Max Temp: $tempMax°C"
val pressure = main.getString("pressure")
val humidity = main.getString("humidity")
val sunrise:Long = sys.getLong("sunrise")
val sunset:Long = sys.getLong("sunset")
val windSpeed = wind.getDouble("speed").toInt()
val weatherDescription = weather.getString("description")
val address = jsonObj.getString("name")+", "+sys.getString("country")
val icon = weather.getString("icon")
val conditionUrl = "https://openweathermap.org/img/wn/$icon#2x.png"
// Populating extracted data into our views
Picasso.get().load(conditionUrl).into(condition_imageView)
findViewById<TextView>(R.id.address).text = address
findViewById<TextView>(R.id.updated_at).text = updatedAtText
findViewById<TextView>(R.id.status).text = weatherDescription.capitalize()
findViewById<TextView>(R.id.temp).text = tempText
findViewById<TextView>(R.id.temp_min).text = tempMinText
findViewById<TextView>(R.id.temp_max).text = tempMaxText
findViewById<TextView>(R.id.sunrise).text = SimpleDateFormat("HH:mm", Locale.ENGLISH).format(Date(sunrise * 1000))
findViewById<TextView>(R.id.sunset).text = SimpleDateFormat("HH:mm", Locale.ENGLISH).format(Date(sunset * 1000))
findViewById<TextView>(R.id.wind).text = "$windSpeed km/h"
findViewById<TextView>(R.id.pressure).text = "$pressure mb"
findViewById<TextView>(R.id.humidity).text = "$humidity %"
// Views populated, hiding the loader, showing the main design
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<RelativeLayout>(R.id.mainContainer).visibility = View.VISIBLE
}
catch (e: Exception){
findViewById<ProgressBar>(R.id.loader).visibility = View.GONE
findViewById<TextView>(R.id.errorText).visibility = View.VISIBLE
}
}
}
#SuppressLint("MissingPermission")
private fun getLastLocation() {
if(CheckPermission()){
if(isLocationEnabled()){
fusedLocationProviderClient.lastLocation.addOnCompleteListener{task ->
var location = task.result
if(location == null){
getNewLocation()
}else {
locationResult = location
}
}
}else{
Toast.makeText(this, "Location service not enabled", Toast.LENGTH_SHORT).show()
}
}else{
RequestPermission()
}
}
private fun CheckPermission() : Boolean {
if( (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ){
return true
}
return false
}
private fun RequestPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
), PERMISSION_ID
)
}
private fun isLocationEnabled() : Boolean{
var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_ID){
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d(TAG, "Permission granted")
}
}
}
#SuppressLint("MissingPermission")
private fun getNewLocation(){
locationRequest = LocationRequest()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 0
locationRequest.fastestInterval = 0
locationRequest.numUpdates = 2
fusedLocationProviderClient!!.requestLocationUpdates(
locationRequest, locationCallback, null
)
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(p0: LocationResult?){
var lastLocation = p0?.lastLocation
if (lastLocation != null) {
locationResult = lastLocation
}
}
}
}
I found the answer. There is a known bug with getting location. More info on this StackOverflow post.
One needs to put
uses-library android:name="org.apache.http.legacy" android:required="false"/>
in the Android Manifest under the Application tab

FusedLocation not trigger locationcallback for android api <= 21

so I want to get the latitude and longitude from the device, but when I build my application on android Lollipop or API 22 I'm not getting the current latitude and longitude. is this because of android permission or what? here is my code
I'm using play service location version:
implementation 'com.google.android.gms:play-services-location:17.0.0'
LocationUser.kt
class LocationUser(context: Context) {
private var fusedLocation: FusedLocationProviderClient? = null
private val INTERVAL: Long = 300000
private val FASTEST_INTERVAL: Long = 300000
private val REQUEST_LOCATION_PERMISSION = 1
lateinit var locationRequest: LocationRequest
private lateinit var lastLocation: Location
fun startLocationUpdates(context: Context) {
Log.d("LOCATION UPDATE", "started location update")
locationRequest = LocationRequest()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = INTERVAL
locationRequest.fastestInterval = FASTEST_INTERVAL
val builder = LocationSettingsRequest.Builder()
builder.addLocationRequest(locationRequest)
val locationSettingsRequest = builder.build()
val settingsClient = LocationServices.getSettingsClient(context)
settingsClient.checkLocationSettings(locationSettingsRequest)
fusedLocation = LocationServices.getFusedLocationProviderClient(context)
if (ActivityCompat.checkSelfPermission(
context,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
context,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
return
}
fusedLocation!!.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
Log.d("LOCATION UPDATE", "end location update")
}
fun isPermissionGranted(context: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (context.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED
) {
true
} else {
ActivityCompat.requestPermissions(
context as Activity, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION_PERMISSION
)
false
}
} else {
true
}
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation
onLocationChanged(context, locationResult.lastLocation)
super.onLocationResult(locationResult)
}
}
fun onLocationChanged(context: Context, location: Location) {
Log.d("UWUWU", "location changed")
lastLocation = location
val geocoder = Geocoder(context, Locale.getDefault())
val latitude = lastLocation.latitude
val longitude = lastLocation.longitude
val sharedPref = SharedPref(context)
Log.d("latitude", latitude.toString())
Log.d("longitude", longitude.toString())
sharedPref.saveStringPref("latitude_user", latitude.toString())
sharedPref.saveStringPref("longitude_user", longitude.toString())
try {
val addresses: List<Address> = geocoder.getFromLocation(latitude, longitude, 1)
val namaKota = addresses[0].subAdminArea
val namaKecamatan = addresses[0].locality
sharedPref.saveStringPref("alamat_user", "$namaKecamatan, $namaKota")
} catch (e: Exception) {
e.localizedMessage
}
Log.d("UWUWU", "location changed")
}
}
and in the activity I called the class like this
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val REQUEST_LOCATION_PERMISSION = 1
private val REQUESTING_LOCATION_UPDATES_KEY = "requesting_location_update"
private val requestingLocationUpdates = true
val locationUser = LocationUser(this)
#SuppressLint("SimpleDateFormat", "SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
../
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
checkUserGPS()
}
if(locationUser.isPermissionGranted(this)){
locationUser.startLocationUpdates(this)
}
Log.d("GRANTED ?", locationUser.isPermissionGranted(this).toString())
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_setting, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_settings) {
val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
return true
}
return super.onOptionsItemSelected(item)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT).show()
}
}
}
private fun checkUserGPS() {
val dialog = AlertDialog.Builder(this)
dialog.setMessage("GPS tidak aktif, apakah kamu ingin megaktifkannya?")
.setCancelable(false)
.setPositiveButton("iya") { _, which ->
startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 11)
}
.setNegativeButton("tidak") { dialog, _ ->
dialog.cancel()
finish()
}
.create()
.show()
}
override fun onResume() {
locationUser.startLocationUpdates(this)
super.onResume()
}
}
when I see log I noticed that the function of onLocationChange not called when function startLocationUpdates function is called. is this because of permission or what, I'm suffering StackOverflow and get this question which is vice versa with my problem, and I noticed the same thing which is locationcallback is not triggered
FusedLocationProviderClient requestLocationUpdates doesn't trigger LocationCallBack for API 23 above
I'm confused right now
The fused Location Provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.
Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and getLastLocation() is invoked right away in onConnected(), that might not be enough time for the first location to arrive..
I suggest you to launch the Maps app first, so that there is at least some confirmed location, and then test your app.

requestLocationUpdates doesn't call the locationCallback

I started to make a Kotlin app and i'm trying to access the users location. It's all my app must do. However, the function "client.requestLocationUpdates(locationRequest, locationCallback, null)" never calls my locationCallback method and I don't know why. I already debug this code, it execute the "client.requestLocationUpdates(locationRequest, locationCallback, null)" line but it never execute my LocationCallbackFunction. Here's my code:
class MainActivity : AppCompatActivity() {
private lateinit var client : FusedLocationProviderClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
client = LocationServices.getFusedLocationProviderClient(this)
}
override fun onResume() {
super.onResume()
var codigo = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
codigo = 0
when (codigo) {
ConnectionResult.SERVICE_MISSING,
ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED,
ConnectionResult.SERVICE_DISABLED -> {
GoogleApiAvailability.getInstance().getErrorDialog(this, codigo, 0, DialogInterface.OnCancelListener {
fun onCancel(dialog: DialogInterface?) {
finish();
}
}).show()
}
ConnectionResult.SUCCESS -> {
println("Google Play Service is working!")
}
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
println("This app hasn't permission to access users location")
return;
}
val locationRequest = LocationRequest.create()
val fifteen = 15 * 1000.toLong()
val five = 5 * 1000.toLong()
locationRequest.interval = fifteen
locationRequest.fastestInterval = five
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
var builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
var settingsClient = LocationServices.getSettingsClient(this)
settingsClient.checkLocationSettings(builder.build())
.addOnSuccessListener(
fun (locationSettingsResponse : LocationSettingsResponse) {
println("locationSettingsResponse.locationSettingsStates.isGpsPresent = ${locationSettingsResponse.locationSettingsStates.isGpsPresent}")
println("locationSettingsResponse.locationSettingsStates.isGpsUsable = ${locationSettingsResponse.locationSettingsStates.isGpsUsable}")
}
)
.addOnFailureListener(
fun (e: Exception) : Unit {
if (e is ResolvableApiException) {
try {
var resolvable : ResolvableApiException = e
resolvable.startResolutionForResult(this, 10);
} catch (e1 : IntentSender.SendIntentException ) {
}
}
}
)
val locationCallback : LocationCallback? = object : LocationCallback() {
override fun onLocationResult(locationResult : LocationResult?) {
if (locationResult == null) {
println("the value is null")
return;
}
for ( location : Location in locationResult.getLocations()) {
location.getLatitude()
println("latitude=" + location.getLatitude());
textoPrincipal.text = location.getLatitude().toString()
}
}
}
client.requestLocationUpdates(locationRequest, locationCallback, null)
}
}
That is the entire content of my activity
I solved this, and I don't know how, this exactly code is running perfectly right now. It was a error in my Android Studio configuration, I guess

Move marker instead of adding it after requestLocationUpdates in kotlin

I'm using google map in kotlin with help of this tutorial Introduction to Google Maps API for Android with Kotlin. in this tutorial showed how can add a marker after location updated but when it updated,there is still a marker in previous location and added again and again. there is no object of Marker in this code and i want remain first added marker and then move it. how can i do this? Thanks
class MapsActivity : AppCompatActivity(), OnMapReadyCallback,
GoogleMap.OnMarkerClickListener {
private lateinit var map: GoogleMap
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var lastLocation: Location
private lateinit var locationCallback: LocationCallback
private lateinit var locationRequest: LocationRequest
private var locationUpdateState = false
companion object {
private const val LOCATION_PERMISSION_REQUEST_CODE = 1
private const val REQUEST_CHECK_SETTINGS = 2
private const val PLACE_PICKER_REQUEST = 3
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
locationCallback = object : LocationCallback() {
override fun onLocationResult(p0: LocationResult) {
super.onLocationResult(p0)
lastLocation = p0.lastLocation
placeMarkerOnMap(LatLng(lastLocation.latitude, lastLocation.longitude))
}
}
createLocationRequest()
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setOnClickListener {
loadPlacePicker()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CHECK_SETTINGS) {
if (resultCode == Activity.RESULT_OK) {
locationUpdateState = true
startLocationUpdates()
}
}
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
val place = PlacePicker.getPlace(this, data)
var addressText = place.name.toString()
addressText += "\n" + place.address.toString()
placeMarkerOnMap(place.latLng)
}
}
}
override fun onPause() {
super.onPause()
fusedLocationClient.removeLocationUpdates(locationCallback)
}
public override fun onResume() {
super.onResume()
if (!locationUpdateState) {
startLocationUpdates()
}
}
override fun onMapReady(googleMap: GoogleMap) {
map = googleMap
map.uiSettings.isZoomControlsEnabled = true
map.setOnMarkerClickListener(this)
setUpMap()
}
override fun onMarkerClick(p0: Marker?) = true
private fun setUpMap() {
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
return
}
map.isMyLocationEnabled = true
map.mapType = GoogleMap.MAP_TYPE_NORMAL
fusedLocationClient.lastLocation.addOnSuccessListener(this) { location ->
// Got last known location. In some rare situations this can be null.
if (location != null) {
lastLocation = location
val currentLatLng = LatLng(location.latitude, location.longitude)
placeMarkerOnMap(currentLatLng)
map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 12f))
}
}
}
private fun placeMarkerOnMap(location: LatLng) {
val markerOptions = MarkerOptions().position(location)
val titleStr = getAddress(location) // add these two lines
markerOptions.title(titleStr)
map.addMarker(markerOptions)
}
private fun startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
LOCATION_PERMISSION_REQUEST_CODE)
return
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null /* Looper */)
}
private fun createLocationRequest() {
locationRequest = LocationRequest()
locationRequest.interval = 10000
locationRequest.fastestInterval = 5000
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
val client = LocationServices.getSettingsClient(this)
val task = client.checkLocationSettings(builder.build())
task.addOnSuccessListener {
locationUpdateState = true
startLocationUpdates()
}
task.addOnFailureListener { e ->
if (e is 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().
e.startResolutionForResult(this#MapsActivity,
REQUEST_CHECK_SETTINGS)
} catch (sendEx: IntentSender.SendIntentException) {
// Ignore the error.
}
}
}
}
private fun loadPlacePicker() {
val builder = PlacePicker.IntentBuilder()
try {
startActivityForResult(builder.build(this#MapsActivity), PLACE_PICKER_REQUEST)
} catch (e: GooglePlayServicesRepairableException) {
e.printStackTrace()
} catch (e: GooglePlayServicesNotAvailableException) {
e.printStackTrace()
}
}
}
The addMarker() method of GoogleMap returns a Marker.
You need to keep a reference to the returned marker and later update it's position using the setPosition method.
#LordRaydenMK's answer is correct. I spent a week trying to work this out and found finally got it. That raywenderlich tutorial you referenced is good, except they incorrectly coded the placeMarkerOnMap() function.
First, set a variable for your location marker above onCreate:
private var userLocationMarker: Marker? = null
Then replace your placeMarkerOnMap() function with this code and it should work fine:
private fun placeMarkerOnMap(location: Location) {
val latLng = LatLng(location.latitude, location.longitude)
if (userLocationMarker == null) {
//Create a new marker
val markerOptions = MarkerOptions()
markerOptions.position(latLng)
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_user_location))
markerOptions.rotation(location.bearing)
markerOptions.anchor(0.5.toFloat(), 0.5.toFloat())
userLocationMarker = map.addMarker(markerOptions)
map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 20f))
} else {
//use the previously created marker
userLocationMarker!!.position = latLng
userLocationMarker!!.rotation = location.bearing
map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 20f))
}
}
If you want to get rid of the blue dot make sure to set isMyLocationEnabled to false.

Categories

Resources