Получить местоположение android Kotlin
Недавно я добавил функцию определения местоположения. Когда я пытаюсь показать долготу и широту, он возвращает ноль.
Этот класс LocationListener:
inner class MylocationListener: LocationListener {
constructor():super(){
mylocation= Location("me")
mylocation!!.longitude
mylocation!!.latitude
}
override fun onLocationChanged(location: Location?) {
mylocation=location
}
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {}
override fun onProviderEnabled(p0: String?) {}
override fun onProviderDisabled(p0: String?) {}
}
И это моя функция GetUserLocation:
fun GetUserLocation(){
var mylocation= MylocationListener()
var locationManager=getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0.1f,mylocation)
}
И эта моя функция вернуть мою долготу и широту:
fun getLoction (view: View){
prgDialog!!.show();
GetUserLocation()
button.setTextColor(getResources().getColor(R.color.green));
textView.text = mylocation!!.latitude.toFloat().toString()
Toast.makeText(this, mylocation!!.latitude.toFloat().toString(), Toast.LENGTH_LONG).show()
Toast.makeText(this, mylocation!!.longitude.toFloat().toString(), Toast.LENGTH_LONG).show()
prgDialog!!.hide()
}
Ответы
Ответ 1
Когда GetUserLocation
возвращается, locationManager
выходит из области видимости и, по-видимому, уничтожается, что предотвращает onLocationChanged
и предоставление обновлений.
Кроме того, вы определили mylocation
внутри GetUserLocation
чтобы он также вышел из сферы действия и еще больше убил любой шанс или получить обновление.
Вы не mylocation
где и как mylocation
внешняя mylocation
(вне GetUserLocation
), но как она объявляется, она GetUserLocation
тем, что внутри GetUserLocation
. Таким образом, вы не получаете много.
Вот пример того, как вы можете это сделать. (Переменная thetext
определяется в макете xml и доступна с расширениями Kotlin.)
// in the android manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
// allow these through Appliation Manager if necessary
// inside a basic activity
private var locationManager : LocationManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
// Create persistent LocationManager reference
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager?;
fab.setOnClickListener { view ->
try {
// Request location updates
locationManager?.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener);
} catch(ex: SecurityException) {
Log.d("myTag", "Security Exception, no location available");
}
}
}
//define the listener
private val locationListener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
thetext.setText("" + location.longitude + ":" + location.latitude);
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
override fun onProviderEnabled(provider: String) {}
override fun onProviderDisabled(provider: String) {}
}
Ответ 2
Я знаю это поздно, но теперь Google упростил его использование. На сайте разработчика написано, что вам нужно создать клиента:
private lateinit var fusedLocationClient: FusedLocationProviderClient
Тогда на создание получите провайдера:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
}
И, наконец, чтобы узнать свое последнее местоположение, просто позвоните:
//Don't forget to ask for permissions for ACCESS_COARSE_LOCATION
//and ACCESS_FINE_LOCATION
@SuppressLint("MissingPermission")
private fun obtieneLocalizacion(){
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
latitude = location?.latitude
longitude = location?.longitude
}
}
* Протестировано с этой реализацией для определения местоположения (установка в файле приложения вашего приложения)
implementation 'com.google.android.gms:play-services-location:15.0.1'
Для получения дополнительной информации перейдите по этой ссылке:
Получить последнее местоположение
Ответ 3
Я хотел бы помочь кому-то, кто пытается найти место с нуля. Вот ссылка: Kotlin Получить текущее местоположение
Код сначала проверяет, включено или выключено местоположение в устройстве, а затем будет выбирать широту и долготу и будет постоянно обновлять его.
В файле build.gradle(Module: app) поместите это
compile 'com.google.android.gms:play-services:11.8.0'
Activity_main.xml код
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Latitude:"
android:textSize="18sp" />
<TextView
android:id="@+id/latitude_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/latitude"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/latitude"
android:textSize="16sp" />
<TextView
android:id="@+id/longitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Longitude:"
android:layout_marginTop="24dp"
android:textSize="18sp" />
<TextView
android:id="@+id/longitude_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/longitude"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/longitude"
android:textSize="16sp"/>
</RelativeLayout>
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 android.provider.Settings
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
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.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.maps.model.LatLng
class MainActivity : AppCompatActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private var mLatitudeTextView: TextView? = null
private var mLongitudeTextView: TextView? = null
private var mGoogleApiClient: GoogleApiClient? = null
private var mLocation: Location? = null
private var mLocationManager: LocationManager? = null
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 */
private var locationManager: LocationManager? = null
private val isLocationEnabled: Boolean
get() {
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager!!.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager!!.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mLatitudeTextView = findViewById(R.id.latitude_textview) as TextView
mLongitudeTextView = findViewById(R.id.longitude_textview) as TextView
mGoogleApiClient = GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build()
mLocationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
Log.d("gggg","uooo");
checkLocation() //check whether location service is enable or not in your phone
}
@SuppressLint("MissingPermission")
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) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
startLocationUpdates()
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient)
if (mLocation == null) {
startLocationUpdates()
}
if (mLocation != null) {
// mLatitudeTextView.setText(String.valueOf(mLocation.getLatitude()));
//mLongitudeTextView.setText(String.valueOf(mLocation.getLongitude()));
} else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show()
}
}
override fun onConnectionSuspended(i: Int) {
Log.i(TAG, "Connection Suspended")
mGoogleApiClient!!.connect()
}
override fun onConnectionFailed(connectionResult: ConnectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode())
}
override fun onStart() {
super.onStart()
if (mGoogleApiClient != null) {
mGoogleApiClient!!.connect()
}
}
override fun onStop() {
super.onStop()
if (mGoogleApiClient!!.isConnected()) {
mGoogleApiClient!!.disconnect()
}
}
@SuppressLint("MissingPermission")
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) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this)
Log.d("reque", "--->>>>")
}
override fun onLocationChanged(location: Location) {
val msg = "Updated Location: " +
java.lang.Double.toString(location.latitude) + "," +
java.lang.Double.toString(location.longitude)
mLatitudeTextView!!.text = location.latitude.toString()
mLongitudeTextView!!.text = location.longitude.toString()
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
// You can now create a LatLng Object for use with maps
val latLng = LatLng(location.latitude, location.longitude)
}
private fun checkLocation(): Boolean {
if (!isLocationEnabled)
showAlert()
return isLocationEnabled
}
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") { paramDialogInterface, paramInt ->
val myIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(myIntent)
}
.setNegativeButton("Cancel") { paramDialogInterface, paramInt -> }
dialog.show()
}
companion object {
private val TAG = "MainActivity"
}
}
Ответ 4
В 2019 году лучшее официальное решение в Котлине
Google API Client/FusedLocationApi устарели, а Location Manager вообще бесполезен.
Поэтому Google предпочитает объединенный провайдер определения местоположения, используя API определения местоположения сервисов Google Play
"FusedLocationProviderClient" используется для определения местоположения и его лучшего способа экономии заряда аккумулятора и точности
Вот пример кода в kotlin для получения последнего известного местоположения/одноразового местоположения (эквивалент текущего местоположения)
// declare a global variable of FusedLocationProviderClient
private lateinit var fusedLocationClient: FusedLocationProviderClient
// in onCreate() initialize FusedLocationProviderClient
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
/**
* call this method for receive location
* get location and give callback when successfully retrieve
* function itself check location permission before access related methods
*
*/
fun getLastKnownLocation() {
fusedLocationClient.lastLocation
.addOnSuccessListener { location->
if (location != null) {
// use your location object
// get latitude , longitude and other info from this
}
}
}
Если ваше приложение может постоянно отслеживать местоположение, вы должны получать обновления получения местоположения
Проверьте образец для этого в kotlin
// declare a global variable FusedLocationProviderClient
private lateinit var fusedLocationClient: FusedLocationProviderClient
// in onCreate() initialize FusedLocationProviderClient
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
// globally declare LocationRequest
private lateinit var locationRequest: LocationRequest
// globally declare LocationCallback
private lateinit var locationCallback: LocationCallback
/**
* call this method in onCreate
* onLocationResult call when location is changed
*/
private fun getLocationUpdates()
{
fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
locationRequest = LocationRequest()
locationRequest.interval = 50000
locationRequest.fastestInterval = 50000
locationRequest.smallestDisplacement = 170f // 170 m = 0.1 mile
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
if (locationResult.locations.isNotEmpty()) {
// get latest location
val location =
locationResult.lastLocation
// use your location object
// get latitude , longitude and other info from this
}
}
}
}
//start location updates
private fun startLocationUpdates() {
fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
null /* Looper */
)
}
// stop location updates
private fun stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(locationCallback)
}
// stop receiving location update when activity not visible/foreground
override fun onPause() {
super.onPause()
stopLocationUpdates()
}
// start receiving location update when activity visible/foreground
override fun onResume() {
super.onResume()
startLocationUpdates()
}
Убедитесь, что вы позаботились о разрешении Mainfaist и времени выполнения для местоположения
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
и для Gradle добавьте это
implementation 'com.google.android.gms:play-services-location:17.0.0'
Для получения более подробной информации следуйте этим официальным документам
https://developer.android.com/training/location/retrieve-current
https://developer.android.com/training/location/receive-location-updates
https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient