requestLocationUpdates doesn't call the locationCallback - android

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

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

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.

User location not showing on Button Click

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

How to create a background service for location tracking in kotlin

I have the following code for fetching latitude and longitude in kotlin:
class MainActivity : AppCompatActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private val TAG = "MainActivity"
private lateinit var mGoogleApiClient: GoogleApiClient
private var mLocationManager: LocationManager? = null
lateinit var mLocation: Location
private var mLocationRequest: LocationRequest? = null
private val listener: com.google.android.gms.location.LocationListener? = null
private val UPDATE_INTERVAL = (2 * 1000).toLong() /* 10 secs */
private val FASTEST_INTERVAL: Long = 2000 /* 2 sec */
lateinit var locationManager: LocationManager
override fun onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
override fun onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
override fun onConnectionSuspended(p0: Int) {
Log.i(TAG, "Connection Suspended");
mGoogleApiClient.connect();
}
override fun onConnectionFailed(connectionResult: ConnectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
override fun onLocationChanged(location: Location) {
var msg = "Updated Location: Latitude " + location.longitude.toString() + location.longitude;
txt_latitude.setText(""+location.latitude);
txt_longitude.setText(""+location.longitude);
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
override fun onConnected(p0: Bundle?) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
startLocationUpdates();
var fusedLocationProviderClient :
FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
fusedLocationProviderClient .getLastLocation()
.addOnSuccessListener(this, OnSuccessListener<Location> { location ->
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
mLocation = location;
txt_latitude.setText("" + mLocation.latitude)
txt_longitude.setText("" + mLocation.longitude)
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MultiDex.install(this)
mGoogleApiClient = GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build()
mLocationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
checkLocation()
}
private fun checkLocation(): Boolean {
if(!isLocationEnabled())
showAlert();
return isLocationEnabled();
}
private fun isLocationEnabled(): Boolean {
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
private fun showAlert() {
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " + "use this app")
.setPositiveButton("Location Settings", DialogInterface.OnClickListener { paramDialogInterface, paramInt ->
val myIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(myIntent)
})
.setNegativeButton("Cancel", DialogInterface.OnClickListener { paramDialogInterface, paramInt -> })
dialog.show()
}
protected fun startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
}
I cannot create this as a background service. I need a background service for fetching location. I am working on a project in which I need to fetch location in background even when the user locks his/her phone or closes the app.

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