How to retrieve current position(latitude & longitude) on Kotlin? - android

I want to retrieve the current position of my phone on Kotlin.
This is my main code (taken from https://androidteachers.com/kotlin-for-android/get-location-in-android-with-kotlin):
package com.anta40.app.locationtest;
import android.Manifest
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AlertDialog
import android.widget.Toast
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.tasks.OnSuccessListener
import kotlinx.android.synthetic.main.activity_main.*
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 onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mGoogleApiClient = GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build()
mLocationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
checkLocation()
}
override fun onStart() {
super.onStart()
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
override fun onStop() {
super.onStop()
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
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)
Toast.makeText(
applicationContext, "Position: (" + mLocation.latitude.toString() + "," +
mLocation.longitude.toString(),
Toast.LENGTH_SHORT
).show()
}
})
}
override fun onConnectionSuspended(p0: Int) {
mGoogleApiClient.connect();
Toast.makeText(applicationContext, "Connection suspended...", Toast.LENGTH_SHORT).show()
}
override fun onConnectionFailed(p0: ConnectionResult) {
Toast.makeText(applicationContext, "Connection error: "+p0.errorMessage, Toast.LENGTH_SHORT).show()
}
override fun onLocationChanged(p0: Location?) {
if (p0 != null) {
Toast.makeText(
applicationContext, "Position: (" + p0.latitude.toString() + "," + p0.longitude.toString(),
Toast.LENGTH_SHORT
).show()
txt_latitude.setText("" + mLocation.latitude)
txt_longitude.setText("" + mLocation.longitude)
}
}
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 run the code on an unrooted Android phone running Android 8 (no SIM card, WiFi only). Location access is already enabled. Yet, the app doesn't display the location. Debugging didn't show any specifc error.
What's wrong here?

Location info needs run time permission after Android SDK 6.0. I couldn't see it in the code you sent.
(https://androidteachers.com/kotlin-for-android/get-location-in-android-with-kotlin)
You should get run time permission in this case
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; }
You can sample here; (https://developer.android.com/training/permissions/requesting)
Or
You can give permission on devices application setting. (Only Test Usage)

Related

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

How can I get continuous location updates in Android?

The GoogleApiClient has been depreceted and now I am having some trouble learning the latest way to get constant location updates. Also, can I get the location updates using LocationCallback and LocationRequetMethod??
I am glad that I finally found it. The code is short. I have used LocationRequest and LocationCallback method. Also, I have used the fusedLocationProviderClient for requestLocationUpdates.
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient fusedLocationProviderClient;
TextView locationTextView;
LocationRequest locationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationTextView = findViewById(R.id.location_text);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
//Not the best practices to get runtime permissions, but still here I ask permissions.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
}
//Instantiating the Location request and setting the priority and the interval I need to update the location.
locationRequest = locationRequest.create();
locationRequest.setInterval(100);
locationRequest.setFastestInterval(50);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//instantiating the LocationCallBack
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult != null) {
if (locationResult == null) {
return;
}
//Showing the latitude, longitude and accuracy on the home screen.
for (Location location : locationResult.getLocations()) {
locationTextView.setText(MessageFormat.format("Lat: {0} Long: {1} Accuracy: {2}", location.getLatitude(),
location.getLongitude(), location.getAccuracy()));
}
}
}
};
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
}
}
In activity_main.xml
<TextView
android:id="#+id/location_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/andika"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Also, before all these, I have added this in my dependencies
implementation 'com.google.android.gms:play-services-location:17.0.0'
And this in my Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
And this keeps on updating in intervals you choose
Hi so continious location update is something you should avoid as it drains battery. You can use locationlistner where you could listen to location change. Say you want to update the location and get the attitude and longitude on every 10 meter change.
Sample code to check last,long every 100 meter
class LocationService : Service(), LocationListener {
protected var locationManager: LocationManager? = null
var checkGPS = false
var checkNetwork = false
// boolean canGetLocation = false;
var loc: Location? = null
// double latitude;
// double longitude;
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onLocationChanged(location: Location) {
// Toast.makeText(getApplicationContext(), Double.toString(location.getLatitude()) + location.getLongitude(), Toast.LENGTH_LONG).show();
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
override fun onProviderEnabled(provider: String) {}
override fun onProviderDisabled(provider: String) {}
override fun onCreate() {
super.onCreate()
location
}
Toast.makeText(getApplicationContext(), Double.toString(latitude) + longitude + "from method", Toast.LENGTH_LONG).show();
private val location: Location?
private get() {
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) !=
PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
}
locationManager = applicationContext
.getSystemService(LOCATION_SERVICE) as LocationManager
checkGPS = locationManager!!
.isProviderEnabled(LocationManager.GPS_PROVIDER)
checkNetwork = locationManager!!
.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
locationManager!!.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES.toFloat(), this
)
if (locationManager != null) {
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
if (location != null) {
Toast.makeText(
applicationContext,
java.lang.Double.toString(location.latitude) + location.longitude + "from method",
Toast.LENGTH_LONG
).show()
}
}
}
Toast.makeText(getApplicationContext(), Double.toString(latitude) + longitude + "from method", Toast.LENGTH_LONG).show();
return loc
}
companion object {
private const val MIN_DISTANCE_CHANGE_FOR_UPDATES: Long = 100
private const val MIN_TIME_BW_UPDATES: Long = 30
}
}

How can I get my location with Kotlin dev Android?

I'm making a Google Maps app. I've put on the API key, and the default code runs without any problems, but I don't know how to localize my position...
I looked around and found this document:
Kotlin API
But still when I try to import:
import com.google.android.location.Location
the first "location" will appear in red... It looks like this API document is deprecated, so I don't know what to import or use to build my app...
How can I fix this?
Try this code for getting the current location:
File activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/latTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Latitude: "/>
<TextView
android:id="#+id/lonTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Longitude: "/>
</LinearLayout>
File MainActivity.kt
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*
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()
}
}
}
}
See here for more details: Getting Current Location (latitude, longitude) in Android using Kotlin

How to get coordinate from fixed marker at center of google maps in android

In my application I'm trying to get coordinate from fixed marker at center of google maps. When i scroll map, i want to get coordinate and set it on the text view.
Here is my Kotlin code:
class ActivityMapsDSPBng : AppCompatActivity(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener {
...
private val TAG = "ActivityMapsDSPBng"
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()
private val FASTEST_INTERVAL: Long = 2000
lateinit var locationManager: LocationManager
override fun onStart() {
...
}
override fun onStop() {
...
}
override fun onConnectionSuspended(p0: Int) {
...
}
override fun onConnectionFailed(connectionResult: ConnectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.errorCode)
}
override fun onLocationChanged(location: Location) {
var msg = "Update Location: Latitude " + location.latitude.toString() + " Longitude " + location.longitude.toString()
tv_dspbg_lat.setText("" + location.latitude)
tv_dspbg_long.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.lastLocation
.addOnSuccessListener(this, OnSuccessListener<Location> { location ->
if (location != null){
mLocation = location
tv_dspbg_lat.setText("" + mLocation.latitude)
tv_dspbg_long.setText("" + mLocation.longitude)
}
})
}
protected fun startLocationUpdates(){
// Create 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)
}
override fun onCreate(savedInstanceState: Bundle?) {
...
val mapsDSPBNGfragment = supportFragmentManager
.findFragmentById(R.id.maps_dspbg) as SupportMapFragment
mapsDSPBNGfragment.getMapAsync(this)
fusedLPCBg = LocationServices.getFusedLocationProviderClient(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{
...
}
private fun isLocationEnabled(): Boolean{
...
}
private fun showAlert(){
val dialog = AlertDialog.Builder(this)
dialog.setTitle("Enable Location")
.setMessage("Your location setting 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()
}
}
I build code from https://androidteachers.com/kotlin-for-android/get-location-in-android-with-kotlin/
When I scrool maps, coordinates do not change according to the fixed maker.
Check my Java code. The fixed marker you are talking about is like an overlay View from your layout code. But if it's right at the center of the map, you can use the center of the camera:
mGoogleMap.setOnCameraIdleListener(new OnCameraIdleListener() {
#Override
public void onCameraIdle() {
// Get the center coordinate of the map, if the overlay view is center too
CameraPosition cameraPosition = mGoogleMap.getCameraPosition();
LatLng currentCenter = cameraPosition.target;
// Or get any coordinate if overlay view is not at the centered
// int[] location = new int[2];
// mOverlayView.getLocationInWindow(location);
// Point viewPosition = new Point(location[0], location[1]);
// LatLng currentCenter = mGoogleMap.getProjection().fromScreenLocation(viewPosition);
}
}
To get the center location of google map
LatLng centerLatLang = mMap.getProjection().getVisibleRegion().latLngBounds.getCenter();

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.

Categories

Resources