【问题标题】:Get user's current location - Kotlin获取用户当前位置 - Kotlin
【发布时间】:2018-11-04 15:58:27
【问题描述】:

伙计们,我正在尝试获取用户位置,但出现了问题,当我运行我的应用程序时,没有播放器图标并且位置错误 - 它仍然显示 lat = 0.0, lon = 0.0。我不使用模拟器,我在手机上测试应用程序(如果重要,Android 4.4.2)。请看一下我的代码,也许我看不到错误。先感谢您!

class MapsActivity : FragmentActivity(), OnMapReadyCallback {

private var mMap: GoogleMap? = null

private val USER_LOCATION_REQUEST_CODE = 1000

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_maps)
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    val mapFragment = supportFragmentManager
        .findFragmentById(R.id.map) as SupportMapFragment
    mapFragment.getMapAsync(this)

    requestLocationPermission()
}

/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap
}

//ask permission
private fun requestLocationPermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) !=
            PackageManager.PERMISSION_GRANTED) {

            requestPermissions(
                arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                USER_LOCATION_REQUEST_CODE
            )
        }
    }
}


fun GetPlayerLocation() {
    Toast.makeText(this, "User location access on", Toast.LENGTH_LONG).show()

    var playerLocation = PlayerLocationListener()

    var locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3, 3f, playerLocation)

    var mythread = myThread()
    mythread.start()
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {

    when (requestCode) {

        USER_LOCATION_REQUEST_CODE -> {

            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                GetPlayerLocation()
            } else {
                Toast.makeText(this, "We cannot access to your location", Toast.LENGTH_LONG).show()
            }
        }
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

var location: Location? = null

// Get player location
inner class PlayerLocationListener : LocationListener {

    constructor() {
        location = Location("Start")
        location!!.latitude = 0.0
        location!!.longitude = 0.0
    }

    override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
    }

    override fun onProviderEnabled(p0: String?) {
    }

    override fun onProviderDisabled(p0: String?) {
    }

    override fun onLocationChanged(p0: Location?) {
        location = p0
    }

}

inner class myThread : Thread {
    constructor() : super(){

    }
    override fun run() {

        while (true) {

            try {
                runOnUiThread {

                    mMap!!.clear()
                    val sydney = LatLng(location!!.latitude, location!!.longitude)
                    mMap!!.addMarker(
                        MarkerOptions().position(sydney).title("Hi!")
                            .snippet("Let's go!")
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.player)))
                    mMap!!.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 14f))
                }
                Thread.sleep(1000)

            } catch (ex: Exception) {
            }
        }
    }

}

}

`

【问题讨论】:

    标签: android google-maps kotlin google-api location


    【解决方案1】:

    试试这个方法

    在 gradle 中实现这些依赖

    implementation 'com.google.android.gms:play-services:11.4.0'
    implementation 'com.google.android.gms:play-services-maps:11.4.0'
    

    在您的AndroidManifest.xml 中使用权限

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

    创建一个locationListener 接口

    interface locationListener {
        fun locationResponse(locationResult: LocationResult)
    }
    

    然后创建一个Location.kt

    class Location (var activity: AppCompatActivity, locationListener: locationListener){
        private val permissionFineLocation=android.Manifest.permission.ACCESS_FINE_LOCATION
        private val permissionCoarseLocation=android.Manifest.permission.ACCESS_COARSE_LOCATION
    
        private val REQUEST_CODE_LOCATION=100
    
        private var fusedLocationClient: FusedLocationProviderClient?=null
    
        private var locationRequest: LocationRequest?=null
        private var callbabck: LocationCallback?=null
        init {
            fusedLocationClient= FusedLocationProviderClient(activity.applicationContext)
    
            inicializeLocationRequest()
            callbabck=object: LocationCallback(){
                override fun onLocationResult(p0: LocationResult?) {
                    super.onLocationResult(p0)
    
                    locationListener.locationResponse(p0!!)
                }
            }
        }
    
        private fun inicializeLocationRequest() {
            locationRequest= LocationRequest()
            locationRequest?.interval=50000
            locationRequest?.fastestInterval=5000
            locationRequest?.priority=LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        private fun validatePermissionsLocation():Boolean{
            val fineLocationAvailable= ActivityCompat.checkSelfPermission(activity.applicationContext, permissionFineLocation)== PackageManager.PERMISSION_GRANTED
            val coarseLocationAvailable=ActivityCompat.checkSelfPermission(activity.applicationContext, permissionCoarseLocation)==PackageManager.PERMISSION_GRANTED
    
            return fineLocationAvailable && coarseLocationAvailable
        }
        private fun requestPermissions(){
            val contextProvider=ActivityCompat.shouldShowRequestPermissionRationale(activity, permissionFineLocation)
    
            if(contextProvider){
                Toast.makeText(activity.applicationContext, "Permission is required to obtain location", Toast.LENGTH_SHORT).show()
            }
            permissionRequest()
        }
        private fun permissionRequest(){
            ActivityCompat.requestPermissions(activity, arrayOf(permissionFineLocation, permissionCoarseLocation), REQUEST_CODE_LOCATION)
        }
        fun onRequestPermissionsResult(requestCode:Int, permissions:Array<out String>, grantResults:IntArray){
            when(requestCode){
                REQUEST_CODE_LOCATION->{
                    if(grantResults.size>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                        getLocation()
                    }else{
                        Toast.makeText(activity.applicationContext, "You did not give permissions to get location", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }
        fun stopUpdateLocation(){
            this.fusedLocationClient?.removeLocationUpdates(callbabck)
        }
        fun inicializeLocation(){
            if (validatePermissionsLocation()){
                getLocation()
            }else{
                requestPermissions()
            }
        }
        @SuppressLint("MissingPermission")
        private fun getLocation() {
            validatePermissionsLocation()
            fusedLocationClient?.requestLocationUpdates(locationRequest, callbabck, null)
        }
    }
    

    用法

    class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
        var location: Location?=null
        private var mMap: GoogleMap? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_maps)
            // Obtain the SupportMapFragment and get notified when the map is ready to be used.
            val mapFragment = supportFragmentManager
                .findFragmentById(R.id.map) as SupportMapFragment
            mapFragment.getMapAsync(this)
            location= Location(this, object :locationListener{
                override fun locationResponse(locationResult: LocationResult) {
                    mMap?.clear()
                    val sydney = LatLng(locationResult.lastLocation.latitude, locationResult.lastLocation.longitude)
                    mMap?.addMarker(MarkerOptions().position(sydney).title("Hi").snippet("Let's go!"))
                    mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 14f))
                }
            })
    
        }
    
        override fun onMapReady(googleMap: GoogleMap) {
            mMap = googleMap
        }
    
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            location?.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
        override fun onStart() {
            super.onStart()
            location?.inicializeLocation()
        }
        override fun onPause() {
            super.onPause()
            location?.stopUpdateLocation()
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 我已经把我的代码改成了你的,但它仍然不起作用 :( 我不知道为什么,只有 0.0 和 0.0 位置的地图......你有什么想法为什么? 滴滴你运行这段代码?
    • @Anna 是的,我在回答之前在物理设备和模拟器中执行代码。可能是设备问题。
    猜你喜欢
    • 2018-12-21
    • 1970-01-01
    • 2011-07-20
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多