Android获取经纬度的最佳实现方式

Android中获取定位信息的方式有很多种,系统自带的LocationManager,以及第三方厂商提供的一些定位sdk,都能帮助我们获取当前经纬度,但第三方厂商一般都需要申请相关的key,且调用量高时,还会产生资费问题。这里采用LocationManager + FusedLocationProviderClient 的方式进行经纬度的获取,以解决普通场景下获取经纬度和经纬度转换地址的功能。

一,添加定位权限

<!--允许获取精确位置,精准定位必选-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--后台获取位置信息,若需后台定位则必选-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!--用于申请调用A-GPS模块,卫星定位加速-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

二,添加依赖库

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
    implementation 'com.google.android.gms:play-services-location:21.0.1'

三,使用LocationManager获取当前经纬度

获取经纬度时,可根据自己的诉求进行参数自定义,如果对经纬度要求不是很精确的可以自行配置Criteria里面的参数。

获取定位前需要先判断相关的服务是否可用,获取定位的服务其实有很多种选择,因为个人项目对经纬度准确性要求较高,为了保证获取的成功率和准确性,只使用了GPS和网络定位两种,如果在国内还会有基站获取等方式,可以自行修改。

import android.Manifest.permission
import android.location.*
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresPermission
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
import kotlin.coroutines.resume


object LocationManagerUtils {
    val TAG = "LocationManagerUtils"

    /**
     * @mLocationManager 传入LocationManager对象
     * @minDistance  位置变化最小距离:当位置距离变化超过此值时,将更新位置信息(单位:米)
     * @timeOut 超时时间,如果超时未返回,则直接使用默认值
     */
    @RequiresPermission(anyOf = [permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION])
    suspend  fun getCurrentPosition(
        mLocationManager: LocationManager,
        timeOut: Long = 3000,
    ):Location{
        var locationListener : LocationListener?=null
        return  try {
            //超时未返回则直接获取失败,返回默认值
            withTimeout(timeOut){
                suspendCancellableCoroutine {continuation ->
                    //获取最佳定位方式,如果获取不到则默认采用网络定位。
                    var bestProvider = mLocationManager.getBestProvider(createCriteria(),true)
                    if (bestProvider.isNullOrEmpty()||bestProvider == "passive"){
                        bestProvider = "network"
                    }
                    Log.d(TAG, "getCurrentPosition:bestProvider:${bestProvider}")
                    locationListener = object : LocationListener {
                        override fun onLocationChanged(location: Location) {
                            Log.d(TAG, "getCurrentPosition:onCompete:${location.latitude},${location.longitude}")
                            if (continuation.isActive){
                                continuation.resume(location)
                                mLocationManager.removeUpdates(this)
                            }
                        }
                        override fun onProviderDisabled(provider: String) {
                        }

                        override fun onProviderEnabled(provider: String) {
                        }
                    }
                    //开始定位
                    mLocationManager.requestLocationUpdates(bestProvider,
                        1000,0f,
                        locationListener!!)
                }
            }
        }catch (e:Exception){
            try {
                locationListener?.let {
                    mLocationManager.removeUpdates(it)
                }
            }catch (e:Exception){
                Log.d(TAG, "getCurrentPosition:removeUpdate:${e.message}")
            }
            //超时直接返回默认的空对象
            Log.d(TAG, "getCurrentPosition:onError:${e.message}")
            return createDefaultLocation()
        }
    }

    @Req
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值