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
Related
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
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
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.
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
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)