一、常用方案
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?=nullvar mLocationListener:LocationListener?=nullvar isSendLocation=truecompanion object {private var singleInstance: LocationManagerUtil? = nullget() {// 懶漢模式if (null == field) {field = LocationManagerUtil()}return field}@Synchronized // 添加注解,線程同步,線程安全fun getInstance(): LocationManagerUtil {return singleInstance!!}}fun registerListener(callback: LocationCallback){isSendLocation=trueunRegisterListener()mLocationManager = WebrtcSdkApplication.instance.getSystemService(Context.LOCATION_SERVICE) as LocationManager?mLocationListener = object : LocationListener {override fun onLocationChanged(location: Location) {if(location!=null){// 當位置發生變化時調用val latitude = location.latitudeval longitude = location.longitudeval provider=location.provider// 使用位置信息XLogUtil.d("${TAG}onLocationChanged longitude:$longitude,,,latitude:$latitude")//在室內或者地下室,gps可能會獲取不到地位,這時先根據網絡定位,待獲取到gps值后,關閉監聽if(provider==LocationManager.GPS_PROVIDER){isSendLocation=falseunRegisterListener()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=nullmLocationListener=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 LocationManagerif (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {// 提示用戶開啟GPSval 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定位結果總是有誤差,可以用這個轉換一下
經緯度轉換為地點:【經緯度查詢】在線地圖經度緯度查詢|經緯度地名坐標轉換