二婴氮、android百度地圖定位顯示當(dāng)前位置(android百度地圖SDK系列)

上一篇文章脾拆,我們知道了如何集成百度地圖并且顯示出來,那么這一篇文章我們就來看看如何對(duì)百度地圖進(jìn)行需要的設(shè)置以及定位并且顯示當(dāng)前的位置莹妒。

一名船、android集成百度地圖(android百度地圖SDK系列)
二、android百度地圖定位顯示當(dāng)前位置(android百度地圖SDK系列)
三旨怠、android百度地圖覆蓋物(android百度地圖SDK系列)

一渠驼、百度地圖基本的配置

我們知道,一個(gè)最基本的地圖是肯定滿足不了我們的需求的鉴腻,所以就要進(jìn)行一些設(shè)置迷扇,來改變地圖百揭。
首先我們看最基本的:

    //地圖控件
    private MapView mapView;
    //百度地圖
    private BaiduMap baiduMap;

    /**
     * 初始化控件
     */
    public void initView(){
        mapView = (MapView)findViewById(R.id.mapView);
    }

    /**
     * 初始化地圖
     */
    public void initMap(){
        //得到地圖實(shí)例
        baiduMap = mapView.getMap();
        /*
        設(shè)置地圖類型
         */
        //普通地圖
        baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        //衛(wèi)星地圖
        //baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
        //空白地圖, 基礎(chǔ)地圖瓦片將不會(huì)被渲染。在地圖類型中設(shè)置為NONE蜓席,將不會(huì)使用流量下載基礎(chǔ)地圖瓦片圖層器一。使用場(chǎng)景:與瓦片圖層一起使用,節(jié)省流量厨内,提升自定義瓦片圖下載速度祈秕。
        //baiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
        //開啟交通圖
        baiduMap.setTrafficEnabled(true);
        //關(guān)閉縮放按鈕
        mapView.showZoomControls(false);
    }

以上代碼就是最基本的設(shè)置了,很簡(jiǎn)單的樣子雏胃,所以不過多停留在此请毛。

二、定位與顯示中心點(diǎn)

說到定位瞭亮,不得不提起android6.0的動(dòng)態(tài)權(quán)限方仿,如果版本小于6.0則不會(huì)有問題,一旦大于等于6.0直接定位就不行了统翩,必須要申請(qǐng)動(dòng)態(tài)權(quán)限仙蚜,所以在這里我就直接將動(dòng)態(tài)權(quán)限簡(jiǎn)單的說一下。不過大家都知道因?yàn)閲?guó)內(nèi)很多廠商對(duì)android系統(tǒng)進(jìn)行所謂的包殼厂汗,所以我們永遠(yuǎn)也摸不清這些殼的尿性鳍征,因此在這里是選擇了PermissionsDispatcher第三方權(quán)限框架來做。
下面我們就來看看它的用法:
首先在build.gradle里加入依賴

compile 'com.github.hotchemi:permissionsdispatcher:2.2.0'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.2.0'

依賴成功后我們先要看看它的幾個(gè)注解和方法:
@NeedsPermission:申請(qǐng)權(quán)限成功時(shí)
@OnShowRationale:申請(qǐng)權(quán)限告訴用戶原因時(shí)
@OnPermissionDenied:申請(qǐng)權(quán)限被拒絕時(shí)
@OnNeverAskAgain:申請(qǐng)權(quán)限被拒絕并勾選不再提醒時(shí)
@RuntimePermissions:注釋此Activity或Fragment面徽,在Make project生成類時(shí)會(huì)用到
onRequestPermissionsResult:回調(diào)方法

首先我們對(duì)需要定位權(quán)限的當(dāng)前Activity類加上@RuntimePermissions注解:

@RuntimePermissions
public class MainActivity extends AppCompatActivity {}

下面我們使用上面剩下的注解和方法來完成對(duì)權(quán)限的動(dòng)態(tài)申請(qǐng):

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // NOTE: delegate the permission handling to generated method
        MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

    /**
     * 申請(qǐng)權(quán)限成功時(shí)
     */
    @NeedsPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
    void ApplySuccess() {
    }

    /**
     * 申請(qǐng)權(quán)限告訴用戶原因時(shí)
     * @param request
     */
    @OnShowRationale(Manifest.permission.ACCESS_COARSE_LOCATION)
    void showRationaleForMap(PermissionRequest request) {
        showRationaleDialog("使用此功能需要打開定位的權(quán)限", request);
    }

    /**
     * 申請(qǐng)權(quán)限被拒絕時(shí)
     *
     */
    @OnPermissionDenied(Manifest.permission.ACCESS_COARSE_LOCATION)
    void onMapDenied() {
        Toast.makeText(this,"你拒絕了權(quán)限艳丛,該功能不可用",Toast.LENGTH_LONG).show();
    }

    /**
     * 申請(qǐng)權(quán)限被拒絕并勾選不再提醒時(shí)
     */
    @OnNeverAskAgain(Manifest.permission.ACCESS_COARSE_LOCATION)
    void onMapNeverAskAgain() {
        AskForPermission();
    }

    /**
     * 告知用戶具體需要權(quán)限的原因
     * @param messageResId
     * @param request
     */
    private void showRationaleDialog(String messageResId, final PermissionRequest request) {
        new AlertDialog.Builder(this)
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(@NonNull DialogInterface dialog, int which) {
                        request.proceed();//請(qǐng)求權(quán)限
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(@NonNull DialogInterface dialog, int which) {
                        request.cancel();
                    }
                })
                .setCancelable(false)
                .setMessage(messageResId)
                .show();
    }

    /**
     * 被拒絕并且不再提醒,提示用戶去設(shè)置界面重新打開權(quán)限
     */
    private void AskForPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("當(dāng)前應(yīng)用缺少定位權(quán)限,請(qǐng)去設(shè)置界面打開\n打開之后按兩次返回鍵可回到該應(yīng)用哦");
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                return;
            }
        });
        builder.setPositiveButton("設(shè)置", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.setData(Uri.parse("package:" + MainActivity.this.getPackageName())); // 根據(jù)包名打開對(duì)應(yīng)的設(shè)置界面
                startActivity(intent);
            }
        });
        builder.create().show();
    }

我們可以看到其中四個(gè)注解后面跟得有參數(shù),這個(gè)參數(shù)就是我們需要申請(qǐng)的權(quán)限趟紊。然后在onRequestPermissionsResult里出現(xiàn)了以下一句代碼:

MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);

這句代碼里的類和方法是沒有的氮双,它是通過對(duì)Activity或者Fragment@RuntimePermissions注解后并且進(jìn)行Make project后才出現(xiàn)的。
至此霎匈,定位權(quán)限的動(dòng)態(tài)申請(qǐng)就搞定了戴差,上面只是該框架的簡(jiǎn)單用法。更加全面的文檔:PermissionsDispatcher

既然權(quán)限搞定了铛嘱,那么我們就可以一鼓作氣的完成的定位并顯示了暖释。
1.我們?cè)谥暗腎nitMap方法里加上以下代碼:

    // 開啟定位圖層
    baiduMap.setMyLocationEnabled(true);
    //聲明LocationClient類
    mLocationClient = new LocationClient(this);
    //注冊(cè)監(jiān)聽函數(shù)
    mLocationClient.registerLocationListener(myListener);
    initLocation();
    //開始定位
    mLocationClient.start();

2.聲明一些需要的變量,配置定位參數(shù)墨吓,實(shí)現(xiàn)定位監(jiān)聽方法球匕,設(shè)置中心點(diǎn)和marker

    //防止每次定位都重新設(shè)置中心點(diǎn)和marker
    private boolean isFirstLocation = true;
    //初始化LocationClient定位類
    private LocationClient mLocationClient = null;
    //BDAbstractLocationListener為7.2版本新增的Abstract類型的監(jiān)聽接口,原有BDLocationListener接口
    private BDLocationListener myListener = new MyLocationListener();
    //經(jīng)緯度
    private double lat;
    private double lon;

    /**
     * 配置定位參數(shù)
     */
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        //可選帖烘,默認(rèn)高精度亮曹,設(shè)置定位模式,高精度,低功耗照卦,僅設(shè)備
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可選址貌,默認(rèn)gcj02行疏,設(shè)置返回的定位結(jié)果坐標(biāo)系
        option.setCoorType("bd09ll");
        //可選状知,默認(rèn)0耙箍,即僅定位一次,設(shè)置發(fā)起定位請(qǐng)求的間隔需要大于等于1000ms才是有效的
        int span = 5000;
        option.setScanSpan(span);
        //可選瞬痘,設(shè)置是否需要地址信息故慈,默認(rèn)不需要
        option.setIsNeedAddress(true);
        //可選,默認(rèn)false,設(shè)置是否使用gps
        option.setOpenGps(true);
        //可選图云,默認(rèn)false惯悠,設(shè)置是否當(dāng)GPS有效時(shí)按照1S/1次頻率輸出GPS結(jié)果
        option.setLocationNotify(true);
        //可選邻邮,默認(rèn)false竣况,設(shè)置是否需要位置語(yǔ)義化結(jié)果,可以在BDLocation.getLocationDescribe里得到筒严,結(jié)果類似于“在北京天安門附近”
        option.setIsNeedLocationDescribe(true);
        //可選丹泉,默認(rèn)false,設(shè)置是否需要POI結(jié)果鸭蛙,可以在BDLocation.getPoiList里得到
        option.setIsNeedLocationPoiList(true);
        //可選摹恨,默認(rèn)true,定位SDK內(nèi)部是一個(gè)SERVICE娶视,并放到了獨(dú)立進(jìn)程晒哄,設(shè)置是否在stop的時(shí)候殺死這個(gè)進(jìn)程,默認(rèn)不殺死
        option.setIgnoreKillProcess(false);
        //可選肪获,默認(rèn)false寝凌,設(shè)置是否收集CRASH信息,默認(rèn)收集
        option.SetIgnoreCacheException(false);
        //可選孝赫,默認(rèn)false较木,設(shè)置是否需要過濾GPS仿真結(jié)果,默認(rèn)需要
        option.setEnableSimulateGps(false);
        mLocationClient.setLocOption(option);
    }

    /**
     * 實(shí)現(xiàn)定位監(jiān)聽 位置一旦有所改變就會(huì)調(diào)用這個(gè)方法
     * 可以在這個(gè)方法里面獲取到定位之后獲取到的一系列數(shù)據(jù)
     */
    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            //獲取定位結(jié)果
            location.getTime();    //獲取定位時(shí)間
            location.getLocationID();    //獲取定位唯一ID青柄,v7.2版本新增伐债,用于排查定位問題
            location.getLocType();    //獲取定位類型
            location.getLatitude();    //獲取緯度信息
            location.getLongitude();    //獲取經(jīng)度信息
            location.getRadius();    //獲取定位精準(zhǔn)度
            location.getAddrStr();    //獲取地址信息
            location.getCountry();    //獲取國(guó)家信息
            location.getCountryCode();    //獲取國(guó)家碼
            location.getCity();    //獲取城市信息
            location.getCityCode();    //獲取城市碼
            location.getDistrict();    //獲取區(qū)縣信息
            location.getStreet();    //獲取街道信息
            location.getStreetNumber();    //獲取街道碼
            location.getLocationDescribe();    //獲取當(dāng)前位置描述信息
            location.getPoiList();    //獲取當(dāng)前位置周邊POI信息

            location.getBuildingID();    //室內(nèi)精準(zhǔn)定位下,獲取樓宇I(lǐng)D
            location.getBuildingName();    //室內(nèi)精準(zhǔn)定位下致开,獲取樓宇名稱
            location.getFloor();    //室內(nèi)精準(zhǔn)定位下峰锁,獲取當(dāng)前位置所處的樓層信息
            //經(jīng)緯度
            lat = location.getLatitude();
            lon = location.getLongitude();
            
            //這個(gè)判斷是為了防止每次定位都重新設(shè)置中心點(diǎn)和marker
            if (isFirstLocation) {
                isFirstLocation = false;
                //設(shè)置并顯示中心點(diǎn)
                setPosition2Center(baiduMap, location, true);
            }
        }
    }

    /**
     * 設(shè)置中心點(diǎn)和添加marker
     *
     * @param map
     * @param bdLocation
     * @param isShowLoc
     */
    public void setPosition2Center(BaiduMap map, BDLocation bdLocation, Boolean isShowLoc) {
        MyLocationData locData = new MyLocationData.Builder()
                .accuracy(bdLocation.getRadius())
                .direction(bdLocation.getRadius()).latitude(bdLocation.getLatitude())
                .longitude(bdLocation.getLongitude()).build();
        map.setMyLocationData(locData);

        if (isShowLoc) {
            LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(18.0f);
            map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }

3.最后我們?cè)趏nCreate方法里進(jìn)行android版本的判斷,根據(jù)android版本來決定直接定位顯示還是需要?jiǎng)討B(tài)權(quán)限以及需要在權(quán)限申請(qǐng)成功的方法里調(diào)用initMap方法和生命周期的管理双戳,代碼如下:

    //當(dāng)android系統(tǒng)小于5.0的時(shí)候直接定位顯示祖今,不用動(dòng)態(tài)申請(qǐng)權(quán)限
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        initMap();
    } else {
        MainActivityPermissionsDispatcher.ApplySuccessWithCheck(this);
    }

    /**
    * 申請(qǐng)權(quán)限成功時(shí)
    */
    @NeedsPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
    void ApplySuccess() {
        initMap();
    }

    @Override
    public void onResume() {
        super.onResume();
        //在activity執(zhí)行onResume時(shí)執(zhí)行mMapView. onResume (),實(shí)現(xiàn)地圖生命周期管理
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        //在activity執(zhí)行onPause時(shí)執(zhí)行mMapView. onPause (),實(shí)現(xiàn)地圖生命周期管理
        mapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //在activity執(zhí)行onDestroy時(shí)執(zhí)行mMapView.onDestroy()千诬,實(shí)現(xiàn)地圖生命周期管理
        // 退出時(shí)銷毀定位
        mLocationClient.unRegisterLocationListener(myListener);
        mLocationClient.stop();
        // 關(guān)閉定位圖層
        baiduMap.setMyLocationEnabled(false);
        mapView.onDestroy();
        mapView = null;
    }

最后我們來看看運(yùn)行效果

動(dòng)態(tài)申請(qǐng)權(quán)限.png
定位顯示當(dāng)前位置.png

到此為止耍目,android集成百度地圖的定位與顯示當(dāng)前位置就結(jié)束了,從第一篇文章到第二篇所有的地方我都注釋的比較細(xì)徐绑,以便新手學(xué)習(xí)和參考邪驮。最后因?yàn)槲夜镜捻?xiàng)目中還涉及到了動(dòng)態(tài)添加點(diǎn)和幾何圖形覆蓋物,所以還有有一篇結(jié)尾的文章傲茄,大家耐心等待~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末毅访,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盘榨,更是在濱河造成了極大的恐慌喻粹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件草巡,死亡現(xiàn)場(chǎng)離奇詭異守呜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)山憨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門查乒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人郁竟,你說我怎么就攤上這事玛迄。” “怎么了棚亩?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蓖议,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我讥蟆,道長(zhǎng)勒虾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任攻询,我火速辦了婚禮从撼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钧栖。我一直安慰自己低零,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布拯杠。 她就那樣靜靜地躺著掏婶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪潭陪。 梳的紋絲不亂的頭發(fā)上雄妥,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天最蕾,我揣著相機(jī)與錄音,去河邊找鬼老厌。 笑死瘟则,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的枝秤。 我是一名探鬼主播醋拧,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼淀弹!你這毒婦竟也來了丹壕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤薇溃,失蹤者是張志新(化名)和其女友劉穎菌赖,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沐序,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琉用,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薄啥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辕羽。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逛尚,死狀恐怖垄惧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绰寞,我是刑警寧澤到逊,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站滤钱,受9級(jí)特大地震影響觉壶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜件缸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一铜靶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧他炊,春花似錦争剿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至凿叠,卻和暖如春涩笤,著一層夾襖步出監(jiān)牢的瞬間嚼吞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工蹬碧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舱禽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓恩沽,卻偏偏與公主長(zhǎng)得像呢蔫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子飒筑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容