在 Kotlin 中获取新用户位置不起作用

Posted

技术标签:

【中文标题】在 Kotlin 中获取新用户位置不起作用【英文标题】:Get New User Location in Kotlin Not working 【发布时间】:2020-12-27 01:22:17 【问题描述】:

大家好,

我从类似于下面的教程构建了代码。但是,对于新的 Kotlin 更新,它不允许您在没有权限检查的情况下运行 fusedLocationProviderClient.requestLocationUpdates(parameters),我不确定如何实施。不过应该很简单。

我的问题是在下面的 getNewLocation() 函数中,处理器没有遇到 fusedLocationProviderClient!!.requestLocationUpdates(parameters em>) 以及与之关联的回调(不显示错误或在没有打印声明的情况下不指示)。这是一个主要问题,因为这意味着如果初始请求返回 NULL,我将无法访问用户位置。

我真的希望有人遇到同样的问题,以便我可以帮助解决这个令人沮丧的漏洞。

代码如下:

class MainActivity : AppCompatActivity() 

    lateinit var fusedLocationProviderClient: FusedLocationProviderClient
    lateinit var locationRequest: LocationRequest

    //Permission id
    private var PERMISSION_ID = 1000

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

        //Initiate Fused Location Provider Client
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
        btnLocation.setOnClickListener 
            getLastLocation()
        
    

    //Function to get last location
    @SuppressLint("MissingPermission", "SetTextI18n")
    private fun getLastLocation() 
        if(CheckPermission()) 
            if(isLocationEnabled()) 
                fusedLocationProviderClient.lastLocation.addOnCompleteListener task ->
                    var location = task.result
                    if(location == null) 
                        getNewLocation()
                     else 
                        tv_location.text = "Your current coordinates are :\nLat: " + location.latitude + " ; Long: " + location.longitude +
                                "\nYour City: " + getCityName(location.latitude, location.latitude) + ", Your Country: " + getCountryName(location.latitude, location.longitude)
                    
                
             else 
                Toast.makeText(this, "Please enable your location service", Toast.LENGTH_LONG).show()
            
         else 
            RequestPermission()
        
    

    @SuppressLint("MissingPermission")
    private fun getNewLocation() 
        locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 0
        locationRequest.fastestInterval = 0
        locationRequest.numUpdates = 2
        fusedLocationProviderClient!!.requestLocationUpdates(
            locationRequest,locationCallback,Looper.myLooper()
        )
    

    private val locationCallback = object : LocationCallback() 
        @SuppressLint("SetTextI18n")
        override fun onLocationResult(p0: LocationResult?) 
            var lastLocation = p0?.lastLocation
            if (lastLocation != null) 
                tv_location.text = "Your current coordinates are :\nLat: " + lastLocation.latitude + " ; Long: " + lastLocation.longitude +
                        "\nYour City: " + getCityName(lastLocation.latitude, lastLocation.longitude) + ", Your Country: " + getCountryName(lastLocation.latitude, lastLocation.longitude)
            
        
    


    //Check user permission
    private fun CheckPermission():Boolean  
        if(
            ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED

                ) 
            return true
        

        return false
    
    //Get user permission
    private fun RequestPermission() 
        ActivityCompat.requestPermissions(
            this,
            arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_ID
        )
    
    //Check location service
    private fun isLocationEnabled():Boolean 
        var locationManager :LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
    

    private fun getCityName(lat:Double,lon:Double):String 
        var CityName = ""
        var geoCoder = Geocoder(this, Locale.getDefault())
        var Adress = geoCoder.getFromLocation(lat, lon, 1)
        CityName = Adress.get(0).locality
        return CityName
    

    private fun getCountryName(lat:Double,lon:Double):String 
        var CountryName = ""
        var geoCoder = Geocoder(this, Locale.getDefault())
        var Adress = geoCoder.getFromLocation(lat, lon, 1)
        CountryName = Adress.get(0).countryName
        return CountryName
    

    //Built in function to check permission result
    //Used it just for debugging
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) 
        if (requestCode == PERMISSION_ID) 
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                Log.d("Debug:", "You have the permission")
            
        
    

【问题讨论】:

【参考方案1】:

你需要在你的 Androidmenifest.xml 文件中添加这两个权限

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

【讨论】:

我已经这样做了,但问题仍然存在?一旦进入 getNewLocation(),由于某些奇怪的原因,fusedLocationProviderClient!!.requestLocationUpdates(parameters) 调用就会被跳过。 我已经运行了您的代码,它运行良好。 getNewLocation() 工作..它给了 lat long。它可能是因为设备而发生的。尝试使用其他设备 不行,但是当你请求一个新的位置时它就不行了。在关闭位置的情况下进入应用程序,将其打开,然后在我的情况下重新加载活动或片段,然后它不会返回位置。

以上是关于在 Kotlin 中获取新用户位置不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥请求 http 在 Kotlin 中不起作用?

获取我在 OsmDroid 中的位置不起作用

Android Studio:地理定位不起作用。无法在 Webview 中获取地理位置

当我尝试将图像上传到 Firebase 存储时,putFile 在 kotlin 中不起作用

Kotlin Spring Boot 验证不起作用

位置的 getSpeed() 在 WiFi 上不起作用