最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android原生定位服務(wù)LocationManager

 更新時(shí)間:2022年08月19日 11:03:54   作者:newki  
這篇文章主要為大家介紹了Android原生定位服務(wù)LocationManager實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

現(xiàn)在的應(yīng)用,幾乎每一個(gè) App 都存在定位的邏輯,方便更好的推薦產(chǎn)品或服務(wù),獲取當(dāng)前設(shè)備的經(jīng)緯度是必備的功能了。有些 App 還是以LBS(基于位置服務(wù))為基礎(chǔ)來(lái)實(shí)現(xiàn)的,比如美團(tuán),餓了嗎,不獲取到位置都無(wú)法使用的。

有些同學(xué)覺(jué)得不就是獲取到經(jīng)緯度么,Android 自帶的就有位置服務(wù) LocationManager ,我們無(wú)需引入第三方服務(wù),就可以很方便的實(shí)現(xiàn)定位邏輯。

確實(shí) LocationManager 的使用很簡(jiǎn)單,獲取經(jīng)緯度很方便,我們就無(wú)需第三方的服務(wù)了嗎? 或者說(shuō) LocationManager 有沒(méi)有坑呢?兼容性問(wèn)題怎么樣?獲取不到位置有沒(méi)有什么兜底策略?

一、LocationManager的使用

由于是Android的系統(tǒng)服務(wù),直接 getSystemService 可以獲取到

LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

一般獲取位置有兩種方式 NetWork 與 GPS 。我們可以指定方式,也可以讓系統(tǒng)自動(dòng)提供最好的方式。

// 獲取所有可用的位置提供器
List<String> providerList = locationManager.getProviders(true);
// 可以指定優(yōu)先GPS,再次網(wǎng)絡(luò)定位
if (providerList.contains(LocationManager.GPS_PROVIDER)) {
    provider = LocationManager.GPS_PROVIDER;
} else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {
    provider = LocationManager.NETWORK_PROVIDER;
} else {
    // 當(dāng)沒(méi)有可用的位置提供器時(shí),彈出Toast提示用戶
    return;
}

當(dāng)然我更推薦由系統(tǒng)提供,當(dāng)我的設(shè)備在室內(nèi)的時(shí)候就會(huì)以網(wǎng)絡(luò)的定位提供,當(dāng)設(shè)備在室外的時(shí)候就可以提供GPS定位。

 String provider = locationManager.getBestProvider(criteria, true);

我們可以實(shí)現(xiàn)一個(gè)定位的Service實(shí)現(xiàn)這個(gè)邏輯

/**
 * 獲取定位服務(wù)
 */
public class LocationService extends Service {
    private LocationManager lm;
    private MyLocationListener listener;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @SuppressLint("MissingPermission")
    @Override
    public void onCreate() {
        super.onCreate();
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        listener = new MyLocationListener();
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setAltitudeRequired(false);//不要求海拔
        criteria.setBearingRequired(false);//不要求方位
        criteria.setCostAllowed(true);//允許有花費(fèi)
        criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗
        String provider = lm.getBestProvider(criteria, true);
        YYLogUtils.w("定位的provider:" + provider);
        Location location = lm.getLastKnownLocation(provider);
        YYLogUtils.w("location-" + location);
        if (location != null) {
            //不為空,顯示地理位置經(jīng)緯度
            String longitude = "Longitude:" + location.getLongitude();
            String latitude = "Latitude:" + location.getLatitude();
            YYLogUtils.w("getLastKnownLocation:" + longitude + "-" + latitude);
            stopSelf();
        }
        //第二個(gè)參數(shù)是間隔時(shí)間 第三個(gè)參數(shù)是間隔多少距離,這里我試過(guò)了不同的各種組合,能獲取到位置就是能,不能獲取就是不能
        lm.requestLocationUpdates(provider, 3000, 10, listener);
    }
    class MyLocationListener implements LocationListener {
        // 位置改變時(shí)獲取經(jīng)緯度
        @Override
        public void onLocationChanged(Location location) {
            String longitude = "Longitude:" + location.getLongitude();
            String latitude = "Latitude:" + location.getLatitude();
            YYLogUtils.w("onLocationChanged:" + longitude + "-" + latitude);
            stopSelf();  // 獲取到經(jīng)緯度以后,停止該service
        }
        // 狀態(tài)改變時(shí)
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            YYLogUtils.w("onStatusChanged - provider:"+provider +" status:"+status);
        }
        // 提供者可以使用時(shí)
        @Override
        public void onProviderEnabled(String provider) {
            YYLogUtils.w("GPS開(kāi)啟了");
        }
        // 提供者不可以使用時(shí)
        @Override
        public void onProviderDisabled(String provider) {
            YYLogUtils.w("GPS關(guān)閉了");
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        lm.removeUpdates(listener); // 停止所有的定位服務(wù)
    }
}

使用:定義并動(dòng)態(tài)申請(qǐng)權(quán)限之后即可開(kāi)啟服務(wù)

    fun testLocation() {
        extRequestPermission(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) {
        startService(Intent(mActivity, LocationService::class.java))
        }
    }

這樣我們啟動(dòng)這個(gè)服務(wù)就可以獲取到當(dāng)前的經(jīng)緯度,只是獲取一次,大家如果想再后臺(tái)持續(xù)定位,那么實(shí)現(xiàn)的方式就不同了,我們服務(wù)要設(shè)置為前臺(tái)服務(wù),并且需要額外申請(qǐng)后臺(tái)定位權(quán)限。

話說(shuō)回來(lái),這么使用就一定能獲取到經(jīng)緯度嗎?有沒(méi)有兼容性問(wèn)題

Android 5.0 Oppo

Android 6.0 Oppo海外版

Android 7.0 華為

Android 11 三星海外版

Android 12 vivo

目前測(cè)試不多,也能發(fā)現(xiàn)問(wèn)題,特別是一些低版本,老系統(tǒng)的手機(jī)就可能無(wú)法獲取位置,應(yīng)該是系統(tǒng)的問(wèn)題,這種服務(wù)跟網(wǎng)絡(luò)沒(méi)關(guān)系,開(kāi)不開(kāi)代理都是一樣的。

并且隨著測(cè)試系統(tǒng)的變高,越來(lái)越完善,提供的最好定位方式還出現(xiàn)混合定位 fused 的選項(xiàng)。

那是不是6.0的Oppo手機(jī)太老了,不支持定位了?并不是,百度定位可以獲取到位置的。

既然只使用 LocationManager 有風(fēng)險(xiǎn),有可能無(wú)法獲取到位置,那怎么辦?

二、混合定位

其實(shí)目前百度,高度的定位Api的服務(wù)SDK也不算大,相比地圖導(dǎo)航等比較重的功能,定位的SDK很小了,并且目前都支持海外的定位服務(wù)。并且定位服務(wù)是免費(fèi)的哦。

既然 LocationManager 有可能獲取不到位置,那我們就加入第三方定位服務(wù),比如百度定位。我們同時(shí)使用 LocationManager 和百度定位,哪個(gè)先成功就用哪一個(gè)。(如果LocationManager可用的話,它的定位比百度定位更快的)

完整代碼如下:

@SuppressLint("MissingPermission")
public class LocationService extends Service {
    private LocationManager lm;
    private MyLocationListener listener;
    private LocationClient mBDLocationClient = null;
    private MyBDLocationListener mBDLocationListener;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        createNativeLocation();
        createBDLocation();
    }
    /**
     * 第三方百度定位服務(wù)
     */
    private void createBDLocation() {
        mBDLocationClient = new LocationClient(UIUtils.getContext());
        mBDLocationListener = new MyBDLocationListener();
        //聲明LocationClient類
        mBDLocationClient.registerLocationListener(mBDLocationListener);
        //配置百度定位的選項(xiàng)
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
        option.setCoorType("WGS84");
        option.setScanSpan(10000);
        option.setIsNeedAddress(true);
        option.setOpenGps(true);
        option.SetIgnoreCacheException(false);
        option.setWifiCacheTimeOut(5 * 60 * 1000);
        option.setEnableSimulateGps(false);
        mBDLocationClient.setLocOption(option);
        //開(kāi)啟百度定位
        mBDLocationClient.start();
    }
    /**
     * 原生的定位服務(wù)
     */
    private void createNativeLocation() {
        lm = (LocationManager) getSystemService(LOCATION_SERVICE);
        listener = new MyLocationListener();
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setAltitudeRequired(false);//不要求海拔
        criteria.setBearingRequired(false);//不要求方位
        criteria.setCostAllowed(true);//允許有花費(fèi)
        criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗
        String provider = lm.getBestProvider(criteria, true);
        YYLogUtils.w("定位的provider:" + provider);
        Location location = lm.getLastKnownLocation(provider);
        YYLogUtils.w("location-" + location);
        if (location != null) {
            //不為空,顯示地理位置經(jīng)緯度
            String longitude = "Longitude:" + location.getLongitude();
            String latitude = "Latitude:" + location.getLatitude();
            YYLogUtils.w("getLastKnownLocation:" + longitude + "-" + latitude);
            stopSelf();
        }
        lm.requestLocationUpdates(provider, 3000, 10, listener);
    }
    class MyLocationListener implements LocationListener {
        // 位置改變時(shí)獲取經(jīng)緯度
        @Override
        public void onLocationChanged(Location location) {
            String longitude = "Longitude:" + location.getLongitude();
            String latitude = "Latitude:" + location.getLatitude();
            YYLogUtils.w("onLocationChanged:" + longitude + "-" + latitude);
            stopSelf();  // 獲取到經(jīng)緯度以后,停止該service
        }
        // 狀態(tài)改變時(shí)
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            YYLogUtils.w("onStatusChanged - provider:" + provider + " status:" + status);
        }
        // 提供者可以使用時(shí)
        @Override
        public void onProviderEnabled(String provider) {
            YYLogUtils.w("GPS開(kāi)啟了");
        }
        // 提供者不可以使用時(shí)
        @Override
        public void onProviderDisabled(String provider) {
            YYLogUtils.w("GPS關(guān)閉了");
        }
    }
    /**
     * 百度定位的監(jiān)聽(tīng)
     */
    class MyBDLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            double latitude = location.getLatitude();    //獲取緯度信息
            double longitude = location.getLongitude();    //獲取經(jīng)度信息
            YYLogUtils.w("百度的監(jiān)聽(tīng) latitude:" + latitude);
            YYLogUtils.w("百度的監(jiān)聽(tīng) longitude:" + longitude);
            YYLogUtils.w("onBaiduLocationChanged:" + longitude + "-" + latitude);
            stopSelf();  // 獲取到經(jīng)緯度以后,停止該service
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        // 停止所有的定位服務(wù)
        lm.removeUpdates(listener);
        mBDLocationClient.stop();
        mBDLocationClient.unregisterLocationListener(mBDLocationListener);
    }
}

其實(shí)邏輯都是很簡(jiǎn)單的,并且省略了不少回調(diào)通信的邏輯,這里只涉及到定位的邏輯,別的邏輯我就盡量不涉及到。

百度定位服務(wù)的API申請(qǐng)與初始化請(qǐng)自行完善,這里只是簡(jiǎn)單的使用。并且坐標(biāo)系統(tǒng)一為國(guó)際坐標(biāo),如果需要轉(zhuǎn)gcj02的坐標(biāo)系,可以網(wǎng)上找個(gè)工具類,或者看我之前的文章

獲取到位置之后,如何Service與Activity通信,就由大家自由發(fā)揮了,有興趣的可以看我之前的文章。

總結(jié)

所以說(shuō)Android原生定位服務(wù) LocationManager 還是有問(wèn)題啊,低版本的設(shè)備可能不行,高版本的Android系統(tǒng)又很行,兼容性有問(wèn)題!讓人又愛(ài)又恨。

很羨慕iOS的定位服務(wù),真的好用,我們 Android 的定位服務(wù)真是拉跨,居然還有兼容性問(wèn)題。

我們使用第三方定位服務(wù)和自己的 LocationManager 并發(fā)獲取位置,這樣可以增加容錯(cuò)率。是比較好用的,為什么要加上 LocationManager 呢?

我直接單獨(dú)用第三方的定位服務(wù)不香嗎?可以是可以,但是如果設(shè)備支持 LocationManager 的話,它會(huì)更快一點(diǎn),體驗(yàn)更好。

以上就是Android原生定位服務(wù)LocationManager的詳細(xì)內(nèi)容,更多關(guān)于Android定位LocationManager的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android編程實(shí)現(xiàn)wifi掃描及連接的方法

    Android編程實(shí)現(xiàn)wifi掃描及連接的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)wifi掃描及連接的方法,涉及Android網(wǎng)絡(luò)操作掃描、查找、連接、線程等相關(guān)操作技巧,需要的朋友可以參考下
    2018-02-02
  • Flutter學(xué)習(xí)教程之Route跳轉(zhuǎn)以及數(shù)據(jù)傳遞

    Flutter學(xué)習(xí)教程之Route跳轉(zhuǎn)以及數(shù)據(jù)傳遞

    這篇文章主要給大家介紹了關(guān)于Flutter學(xué)習(xí)教程之Route跳轉(zhuǎn)以及數(shù)據(jù)傳遞的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 實(shí)例探究Android應(yīng)用編寫(xiě)時(shí)Fragment的生命周期問(wèn)題

    實(shí)例探究Android應(yīng)用編寫(xiě)時(shí)Fragment的生命周期問(wèn)題

    這篇文章主要介紹了Android應(yīng)用編寫(xiě)時(shí)Fragment的生命周期問(wèn)題探究,resumed和paused以及stoped三種狀態(tài)的控制需要熟練掌握,需要的朋友可以參考下
    2016-02-02
  • Android中一種效果奇好的混音方法詳解

    Android中一種效果奇好的混音方法詳解

    這篇文章主要給大家介紹了關(guān)于在Android中一種效果奇好的混音方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Android編程開(kāi)發(fā)之TextView單擊鏈接彈出Activity的方法

    Android編程開(kāi)發(fā)之TextView單擊鏈接彈出Activity的方法

    這篇文章主要介紹了Android編程開(kāi)發(fā)之TextView單擊鏈接彈出Activity的方法,涉及Android中TextView控件的相關(guān)操作技巧,需要的朋友可以參考下
    2016-01-01
  • 使用VideoView播放App中的資源文件

    使用VideoView播放App中的資源文件

    這篇文章主要介紹了使用VideoView播放App中的資源文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Android 高德地圖之poi搜索功能的實(shí)現(xiàn)代碼

    Android 高德地圖之poi搜索功能的實(shí)現(xiàn)代碼

    這篇文章主要介紹了android 高德地圖之poi搜索功能的實(shí)現(xiàn)代碼,在實(shí)現(xiàn)此功能時(shí)遇到很多問(wèn)題,在文章都給大家提到,需要的朋友可以參考下
    2017-08-08
  • 淺談React Native打包apk的坑

    淺談React Native打包apk的坑

    下面小編就為大家?guī)?lái)一篇淺談React Native打包apk的坑。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Android編程單元測(cè)試實(shí)例詳解(附源碼)

    Android編程單元測(cè)試實(shí)例詳解(附源碼)

    這篇文章主要介紹了Android編程單元測(cè)試,結(jié)合完整實(shí)例形式詳細(xì)分析了Android單元測(cè)試的具體步驟與相關(guān)技巧,并附帶完整實(shí)例代碼供讀者下載參考,需要的朋友可以參考下
    2015-11-11
  • 記錄Android studio JNI開(kāi)發(fā)的三種方式(推薦)

    記錄Android studio JNI開(kāi)發(fā)的三種方式(推薦)

    JNI (Java Native Interface)是一套編程接口,用來(lái)實(shí)現(xiàn)Java代碼和其他語(yǔ)言(c、C++或匯編)進(jìn)行交互。下面通過(guò)本文給大家講解Android studio JNI開(kāi)發(fā)的三種方式,需要的朋友參考下吧
    2017-12-12

最新評(píng)論

淳安县| 佳木斯市| 苗栗市| 洪湖市| 漠河县| 尖扎县| 安义县| 洛川县| 安庆市| 台江县| 凉山| 天台县| 万宁市| 聂拉木县| 双鸭山市| 开原市| 桦川县| 阜城县| 盱眙县| 当阳市| 太原市| 额尔古纳市| 汝阳县| 邳州市| 库车县| 卓尼县| 遵义县| 浦北县| 娄烦县| 巫溪县| 望都县| 赤城县| 张家界市| 张家港市| 青河县| 南漳县| 尼玛县| 鄱阳县| 德阳市| 秦安县| 沂南县|