Get location android Kotlin

前端 未结 6 1670
傲寒
傲寒 2020-12-13 07:28

I recently added get location function. When I try to show longitude and latitude, it returns zero.

This my LocationListener class:

inner class Myloc         


        
相关标签:
6条回答
  • 2020-12-13 07:39

    I read many of answers but question is get only last known location. With receiver it continuously send latitude and longitude I have solution for this in kotlin.. Give permissions

    <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())
    
            }
    
        }
    
    0 讨论(0)
  • 2020-12-13 07:42

    I would like to help someone who is trying to get location from scratch. Here is the reference: Kotlin Get Current Location

    Code will first check whether location is on or off in device and then will fetch latitude and longitudes and will update it constantly.

    In build.gradle(Module:app) file put this

    compile 'com.google.android.gms:play-services:11.8.0'
    

    activity_main.xml code

    <?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"
        }
    
    }
    
    0 讨论(0)
  • 2020-12-13 07:55

    In 2019 Best Offical Solution in Kotlin

    Google API Client/FusedLocationApi are deprecated and Location Manager is not useful at all. So Google prefer Fused Location Provider Using the Google Play services location APIs "FusedLocationProviderClient" is used to get location and its better way for battery saving and accuracy

    Here is sample code in kotlin to get the last known location /one-time location( equivalent to the current location)

     // 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
                        }
    
                    }
    
        }
    

    If your app can continuously track the location then you have to receive Receive location updates

    Check the sample for that in 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()
            }
    

    Make sure you take care about Mainfaist permission and runtime permission for location

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

    and for Gradle add this

    implementation 'com.google.android.gms:play-services-location:17.0.0'
    

    For more details follow these official documents

    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

    0 讨论(0)
  • 2020-12-13 07:55

    I know it's late, but now Google has made it simpler to use. In the developer site, it says that you need to create a Client:

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    

    Then onCreate get the provider:

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    }
    

    And finally, to get your last location just call:

    //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
                }
    }
    

    *Tested with this implementation for location (Setup in your app gradle file)

    implementation 'com.google.android.gms:play-services-location:15.0.1'
    

    For more info, check this link:

    Obtain last location

    0 讨论(0)
  • 2020-12-13 07:57

    Get location with address in android kotlin

    Add this line in dependencies

    implementation 'com.google.android.gms:play-services-location:17.0.0'
    

    Add this in 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" />
    

    Copy this below code in your class

    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 your code and check the log, Happy Coding

    0 讨论(0)
  • 2020-12-13 08:01

    When GetUserLocation returns, locationManager goes out of scope and presumably is destroyed, preventing onLocationChanged from being called and providing updates.

    Also, you've defined mylocation inside of GetUserLocation so it also goes out of scope and further kills any chance or your getting an update.

    You have not shown where and how the outer mylocation is declared (outside of GetUserLocation), but how ever it is declared, it is being shadowed by the one inside of GetUserLocation. So you aren't getting much.

    Here is an example of how you might do it. (The variable thetext is defined within the layout xml and accessed with Kotlin extensions.)

    // 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.text = ("" + location.longitude + ":" + location.latitude)
        }
        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onProviderDisabled(provider: String) {}
    }
    
    0 讨论(0)
提交回复
热议问题