使用FusedLocationClientProvider无法获得正确的位置

问题描述

大家好,我正在从事一个项目,我正在为此项目使用kotlin。

我有很多事情要做,但是我卡住了一件事情,那就是使用google maps获取用户当前位置。我知道有很多教程,但是我所做的只是来自使用FusedLocationClientProvider的google maps官方文档。一切正常,直到加载并显示用户位置为止,但是我没有找到正确的位置。这表明我在加利福尼亚,但我不知道如何显示正确的位置。

我已附上我用于当前位置的代码

我已经使用文本视图进行测试以显示当前位置。

package com.example.soundsource

import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import android.Manifest
import android.app.Service
import android.content.Context
import android.location.Geocoder
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.util.Log
import android.widget.TextView
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.libraries.places.api.Places
import java.lang.StringBuilder
import java.util.*
import com.google.android.libraries.places.api.net.PlacesClient
import kotlin.math.*


class SoundLocation : AppCompatActivity(),OnMapReadyCallback{

    private var map: GoogleMap? = null

    // The entry point to the Places API.
    private lateinit var placesClient: PlacesClient

    // The entry point to the Fused Location Provider.
    private lateinit var fusedLocationProviderClient: FusedLocationProviderClient

    private lateinit var locationManager:LocationManager

    companion object {
        private val defaultLocation = LatLng(-31.952854,115.857342)
        private var locationPermissionGranted = false
        private const val DEFAULT_ZOOM = 15
        private const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1
        private var lastKNownLocation: Location? = null
        // Keys for storing activity state.
        private const val KEY_CAMERA_POSITION = "camera_position"
        private const val KEY_LOCATION = "location"
    }

    private lateinit var addressLocation:TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sound_location)

        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
        mapFragment?.getMapAsync(this)

       addressLocation = findViewById(R.id.address)

        // Construct a GeoDataClient.
        Places.initialize(applicationContext,getString(R.string.google_maps_key))
        placesClient = Places.createClient(this)

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

    }


    override fun onMapReady(googleMap: GoogleMap?) {
        this.map = googleMap
        map?.mapType = GoogleMap.MAP_TYPE_HYBRID
        getLocationPermission()
        updateLocationUI()
        getDeviceLocation()
    }

    private fun moveCamera(lat:Double,lon:Double,current:String){
        map?.apply {
            addMarker(
                MarkerOptions()
                    .position(LatLng(lat,lon))
                    .title(current)
            )
            moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(lat,lon),10f))
        }
    }

    private fun getAddress(lat:Double,lon:Double): String {
        // distance between two latitude and longitude
        val Perth = LatLng(-31.952854,115.857342)
        val dlat = lat-Perth.latitude
        val dlon = lon-Perth.longitude
        var distance = sin(dlat/2)* sin(dlon/2) + cos(lat)+ cos(lon)*sin(dlat/2)* sin(dlon/2)
        distance = atan2(sqrt(distance),sqrt(1-distance))
        distance *= 6371


        //current location address
        val geoCoder = Geocoder(this,Locale.getDefault())
        val addresses = geoCoder.getFromLocation(lat,lon,1)
        val returnAddress = addresses[0]
        val fullAddress = StringBuilder("")
        for (i in 0..returnAddress.maxAddressLineIndex) {
            fullAddress.append(returnAddress.getAddressLine(i)).append("\n")
        }
        fullAddress.append(" \n ").append(String.format(" %.1f kms",distance))


        return fullAddress.toString()
    }

    private fun updateLocationUI() {
        if (map == null)
            return
        try {
            if (locationPermissionGranted) {
                map?.isMyLocationEnabled = true
                map?.uiSettings?.isMyLocationButtonEnabled = true
            } else {
                map?.isMyLocationEnabled = false
                map?.uiSettings?.isMyLocationButtonEnabled = false
                lastKNownLocation = null
                getLocationPermission()
            }
        } catch (e: SecurityException) {
            Log.e("Exception: %s",e.message,e)
        }
    }

    private fun getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this.applicationContext,Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED 
        ) {
            locationPermissionGranted = true
        } else {
            ActivityCompat.requestPermissions(
                this,arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
            )
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<String>,grantResults: IntArray) {
        locationPermissionGranted = false
        when (requestCode) {
            PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {
                if (grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    locationPermissionGranted = true
                }
            }
        }
        updateLocationUI()
    }

    private fun getDeviceLocation() {
        try {
            if (locationPermissionGranted) {
                val locationResult = fusedLocationProviderClient.lastLocation
                locationResult.addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {

                        lastKNownLocation = task.result
                        if (lastKNownLocation != null) {

                           val currentAddress = getAddress(lastKNownLocation!!.latitude,lastKNownLocation!!.longitude)
                            addressLocation.text = currentAddress
                            moveCamera(lastKNownLocation!!.latitude,lastKNownLocation!!.longitude,currentAddress)
                        }


                    } else {
                        map?.moveCamera(CameraUpdateFactory
                            .newLatLngZoom(defaultLocation,DEFAULT_ZOOM.toFloat()))
                        map?.uiSettings?.isMyLocationButtonEnabled = false
                    }
                }
            }
        } catch (e: SecurityException) {
            Log.e("Exception: %s",e)
        }
    }

}

解决方法

您是否正在模拟器上测试?仿真器没有内置的实际GPS,因此默认情况下,您的位置在加利福尼亚州。不过,您可以从模拟器设置中设置位置。或者只是在真实的电话上进行测试。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...