web-dev-qa-db-fra.com

Obtenir l'emplacement Android Kotlin

J'ai récemment ajouté la fonction get location. Lorsque j'essaie d'afficher la longitude et la latitude, il renvoie zéro.

Cette classe 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?) {}
}

Et ceci ma fonction GetUserLocation:

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

Et ceci ma fonction pour retourner ma longitude et latitude:

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()
} 
11
Nour Medhat

Lorsque GetUserLocation revient, locationManager sort de la portée et est vraisemblablement détruit, empêchant onLocationChanged d'être appelé et fournissant des mises à jour.

De plus, vous avez défini mylocation à l'intérieur de GetUserLocation donc il sort également du champ d'application et tue davantage toute chance ou que vous obteniez une mise à jour.

Vous n'avez pas montré où et comment le mylocation extérieur est déclaré (en dehors de GetUserLocation), mais comment il est déclaré, il est masqué par celui à l'intérieur de GetUserLocation . Vous n'obtenez donc pas grand-chose.

Voici un exemple de la façon dont vous pourriez le faire. (La variable thetext est définie dans le xml de mise en page et accessible avec les extensions 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) {}
}
16
Les

Je sais qu'il est tard, mais maintenant Google a simplifié son utilisation. Dans le site du développeur, il est indiqué que vous devez créer un client:

private lateinit var fusedLocationClient: FusedLocationProviderClient

Ensuite, onCreate obtient le fournisseur:

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

Et enfin, pour obtenir votre dernier emplacement, appelez simplement:

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

* Testé avec cette implémentation pour l'emplacement (configuration dans votre fichier de notes d'application)

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

Pour plus d'informations, consultez ce lien:

Obtenir le dernier emplacement

7
Daniel Miranda

Je voudrais aider quelqu'un qui essaie de se repérer à partir de zéro. Voici la référence: Kotlin Get Current Location

Le code vérifiera d'abord si l'emplacement est activé ou désactivé dans l'appareil, puis récupérera la latitude et les longitudes et le mettra à jour en permanence.

Dans le fichier build.gradle (Module: app), mettez ceci

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

code 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
user6017633

En 2019 Meilleure solution officielle à Kotlin

Google API Client/FusedLocationApi sont obsolètes et Location Manager n'est pas du tout utile. Donc, Google préfère le fournisseur de localisation fusionné En utilisant les API de localisation des services Google Play, "FusedLocationProviderClient" est utilisé pour obtenir la localisation et sa meilleure façon d'économiser la batterie et de précision

Voici un exemple de code dans kotlin pour obtenir le dernier emplacement connu/emplacement unique (équivalent à l'emplacement actuel)

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

                }

    }

Si votre application peut suivre en permanence l'emplacement, vous devez recevoir les mises à jour de l'emplacement de réception

Vérifiez l'échantillon dans 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()
        }

Assurez-vous de prendre soin de l'autorisation Mainfaist et de l'autorisation d'exécution pour l'emplacement

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

et pour Gradle ajouter ceci

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

Pour plus de détails suivez ces documents officiels

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

2
Mayank Sharma