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


1274

被折叠的 条评论
为什么被折叠?



