获取位置android Kotlin

Nou*_*hat 11 android location 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?) {}
}
Run Code Online (Sandbox Code Playgroud)

这是我的GetUserLocation函数:

fun GetUserLocation(){
    var mylocation= MylocationListener()
    var locationManager=getSystemService(Context.LOCATION_SERVICE) as LocationManager
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0.1f,mylocation)
}
Run Code Online (Sandbox Code Playgroud)

这是我的功能,以返回我的经度和纬度:

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()
} 
Run Code Online (Sandbox Code Playgroud)

May*_*rma 33

2019 年 Kotlin 最佳官方解决方案

Google API Client/FusedLocationApi 已弃用,位置管理器根本没有用。 因此,Google 更喜欢 Fused Location Provider 使用 Google Play 服务位置 API“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
                    }

                }

    }
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序可以持续跟踪位置,那么您必须接收接收位置更新

检查 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()
        }
Run Code Online (Sandbox Code Playgroud)

确保您注意位置的 Mainfaist 权限和运行时权限

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Run Code Online (Sandbox Code Playgroud)

对于 Gradle 添加这个

implementation 'com.google.android.gms:play-services-location:17.0.0'
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅这些官方文件

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


Les*_*Les 18

GetUserLocation返回时,locationManager超出范围和可能被破坏,防止onLocationChanged被调用,并提供更新.

此外,您已经定义了mylocation内部,GetUserLocation因此它也超出范围并进一步杀死任何机会或您获得更新.

你没有显示外部mylocation声明的位置和方式(在外面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) {}
}
Run Code Online (Sandbox Code Playgroud)

  • 对于较新的 Android 版本,请求权限非常重要,并在需要时显示解释。我必须为相机、存储和现在的位置执行此操作,因此我创建了一个扩展函数,这可能对其他人有帮助:https://github.com/JCarlosR/Redemnorte/blob/80e82dd9795e945ca093​​d08a9194656971f07485/app/src/main/ java/com/youtube/sorcjc/redemnorte/util/ActivityExtensions.kt#L8 (4认同)

小智 11

在android kotlin中使用地址获取位置

在依赖项中添加这一行

implementation 'com.google.android.gms:play-services-location:17.0.0'
Run Code Online (Sandbox Code Playgroud)

在 AndroidManifest 中添加这个

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Run Code Online (Sandbox Code Playgroud)

在您的班级中复制以下代码

class MainActivity : AppCompatActivity() {

private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationRequest: LocationRequest
private lateinit var locationCallback: LocationCallback

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_splash)
    /*Check location*/
    checkLocation()
}

private fun checkLocation(){
    val manager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        showAlertLocation()
    }
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    getLocationUpdates()
}

private fun showAlertLocation() {
    val dialog = AlertDialog.Builder(this)
    dialog.setMessage("Your location settings is set to Off, Please enable location to use this application")
    dialog.setPositiveButton("Settings") { _, _ ->
        val myIntent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
        startActivity(myIntent)
    }
    dialog.setNegativeButton("Cancel") { _, _ ->
        finish()
    }
    dialog.setCancelable(false)
    dialog.show()
}

private fun getLocationUpdates() {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    locationRequest = LocationRequest()
    locationRequest.interval = 50000
    locationRequest.fastestInterval = 50000
    locationRequest.smallestDisplacement = 170f //170 m = 0.1 mile
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //according to your app
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            if (locationResult.locations.isNotEmpty()) {
                /*val location = locationResult.lastLocation
                Log.e("location", location.toString())*/
                val addresses: List<Address>?
                val geoCoder = Geocoder(applicationContext, Locale.getDefault())
                addresses = geoCoder.getFromLocation(
                    locationResult.lastLocation.latitude,
                    locationResult.lastLocation.longitude,
                    1
                )
                if (addresses != null && addresses.isNotEmpty()) {
                    val address: String = addresses[0].getAddressLine(0)
                    val city: String = addresses[0].locality
                    val state: String = addresses[0].adminArea
                    val country: String = addresses[0].countryName
                    val postalCode: String = addresses[0].postalCode
                    val knownName: String = addresses[0].featureName
                    Log.e("location", "$address $city $state $postalCode $country $knownName")
                }
            }
        }
    }
}

// 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()
}}
Run Code Online (Sandbox Code Playgroud)

运行你的代码并查看日志,Happy Coding


Dan*_*nda 8

我知道已经很晚了,但是现在Google使它更易于使用了。在开发人员站点中,它表明您需要创建一个客户端:

private lateinit var fusedLocationClient: FusedLocationProviderClient
Run Code Online (Sandbox Code Playgroud)

然后onCreate获取提供者:

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
}
Run Code Online (Sandbox Code Playgroud)

最后,要获取您的最后一个位置,只需致电:

//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
            }
}
Run Code Online (Sandbox Code Playgroud)

*使用此实现对位置进行了测试(在应用gradle文件中进行设置)

implementation 'com.google.android.gms:play-services-location:15.0.1'
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请检查此链接:

获取最后一个位置

  • 在某些设备上,当您关闭位置然后将其重新打开时 - 最后的位置将为空 (2认同)

Ran*_*mer 6

我阅读了许多答案,但问题是只获取最后一个已知位置。使用接收器,它会不断发送纬度和经度,我在 kotlin 中对此有解决方案.. 授予权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />




    public fun getLastKnownLocation(context: Context) {
        val locationManager: LocationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        val providers: List<String> = locationManager.getProviders(true)
        var location: Location? = null
        for (i in providers.size - 1 downTo 0) {
            location= locationManager.getLastKnownLocation(providers[i])
            if (location != null)
                break
        }
        val gps = DoubleArray(2)
        if (location != null) {
            gps[0] = location.getLatitude()
            gps[1] = location.getLongitude()
            Log.e("gpsLat",gps[0].toString())
            Log.e("gpsLong",gps[1].toString())

        }

    }
Run Code Online (Sandbox Code Playgroud)


use*_*633 5

我想帮助那些试图从头开始获取位置的人。这是参考:Kotlin 获取当前位置

代码将首先检查设备中的位置是打开还是关闭,然后获取纬度和经度并不断更新它。

在 build.gradle(Module:app) 文件中把这个

compile 'com.google.android.gms:play-services:11.8.0'
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

主活动.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"
    }

}
Run Code Online (Sandbox Code Playgroud)