一、常用方案
1、使用LocationManager GPS和网络定位
缺点:个别设备,室内或者地下停车场获取不到gps定位,故需要和网络定位相结合使用
2、使用Google Play服务
这种方案需要Android手机中有安装谷歌服务,然后导入谷歌的第三方库:
例如:implementation 'com.google.android.gms:play-services-location:20.0.0'
缺点:一些厂商可能会阉割掉谷歌服务
3、使用第三方地图定位
缺点:该方法准确度较高,但需要在第三方平台注册账号和集成key
这里介绍第一种方案,如果获取不到gps,先通过网络定位获取,然后再尝试去获取gps
博主这里就遇到同一个地方,小米可以通过gps获取到数据,但一加的两个手机,都无法通过gps获取到经纬度,故只能先从网络获取经纬度
二、方案实现
class LocationManagerUtil {
val TAG: String = "LocationManagerUtil_"
var mLocationManager:LocationManager?=null
var mLocationListener:LocationListener?=null
var isSendLocation=true
companion object {
private var singleInstance: LocationManagerUtil? = null
get() {
// 懒汉模式
if (null == field) {
field = LocationManagerUtil()
}
return field
}
@Synchronized // 添加注解,线程同步,线程安全
fun getInstance(): LocationManagerUtil {
return singleInstance!!
}
}
fun registerListener(callback: LocationCallback){
isSendLocation=true
unRegisterListener()
mLocationManager = WebrtcSdkApplication.instance.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
mLocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
if(location!=null){
// 当位置发生变化时调用
val latitude = location.latitude
val longitude = location.longitude
val provider=location.provider
// 使用位置信息
XLogUtil.d("${TAG}onLocationChanged longitude:$longitude,,,latitude:$latitude")
//在室内或者地下室,gps可能会获取不到地位,这时先根据网络定位,待获取到gps值后,关闭监听
if(provider==LocationManager.GPS_PROVIDER){
isSendLocation=false
unRegisterListener()
callback.onLocationChanged(longitude,latitude)
}else if(provider==LocationManager.NETWORK_PROVIDER){
if(isSendLocation){
callback.onLocationChanged(longitude,latitude)
}
isSendLocation=false
}
}else{
XLogUtil.d("${TAG}onLocationChanged location==null")
}
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
// 当GPS状态改变时调用
}
override fun onProviderEnabled(provider: String) {
// 当选中的位置提供者被激活时调用
}
override fun onProviderDisabled(provider: String) {
// 当选中的位置提供者被停用时调用
}
}
if (ActivityCompat.checkSelfPermission(
WebrtcSdkApplication.instance,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
WebrtcSdkApplication.instance,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
//Toast.makeText(WebrtcSdkApplication.instance,WebrtcSdkApplication.instance.getString(R.string.please_enable_location_permissions_in_settings),Toast.LENGTH_SHORT).show()
XLogUtil.d("${TAG}checkSelfPermission 定位权限未授权")
}
mLocationManager?.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 5f,
mLocationListener!!
)//更新间隔1000毫秒,距离间隔5米
mLocationManager?.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L, 5f,
mLocationListener!!
)//更新间隔1000毫秒,距离间隔5米
}
fun unRegisterListener(){
if(mLocationListener!=null){
mLocationManager?.removeUpdates(mLocationListener!!)
mLocationManager=null
mLocationListener=null
}
}
}
三、相关权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
<uses-permission android:name="android.permission.INTERNET" />
<!--定位权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
//以下两个权限需要动态申请权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
四、判断是否打开了gps
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// 提示用户开启GPS
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}
五、获取的经纬度在不同地图上显示不一致问题解答
GPS获得的经纬度所用的坐标系和谷歌地图、百度地图上的坐标系是不同的,GPS硬件获得的经纬度是WGS-84标准,国际通用,
可以看成是正常的GPS位置,在google earth上全部坐标,谷歌地图上除中国以外的坐标均为这个标准,但是谷歌地图的中国坐标使用的是GCJ-02标准,
是天朝测绘局在WGS-84的基础上加入随机偏差加密后的一种经纬度,会随机偏移一公里左右,所以导致无论怎样定位总是显示不对。
而百度地图在GCJ-02上又加入了自己的加密算法,变成了BD-09标准,另外其他很多的地图都有自己的加密方法。
这些都是硬件获取经纬度在地图上指示不对的原因,网上有免费做转换的网站,
在这里推荐一个:http://map.yanue.NET/gps.html,如果发现GPS定位结果总是有误差,可以用这个转换一下
经纬度转换为地点:【经纬度查询】在线地图经度纬度查询|经纬度地名坐标转换