第二十二章 Android中使用地理定位服務(wù)——百度地圖

??地理定位服務(wù)對(duì)于我們的開(kāi)發(fā)來(lái)說(shuō)具有重要的作用,目前是市場(chǎng)上的很多App會(huì)選擇獲取你的地理位置信息贪磺,尤其是一些旅游類(lèi),生活類(lèi)的信息服務(wù)App诅愚。例如:飛豬寒锚,美團(tuán),去哪兒旅行违孝,餓了么等刹前。萬(wàn)維網(wǎng)的實(shí)現(xiàn),我們所在的世界就小了雌桑,不管你在哪里喇喉,都是一個(gè)個(gè)二維或者三維的坐標(biāo)。
??基于地理定位服務(wù)的核心就是確定用戶(hù)所在的位置校坑。通常有兩種技術(shù)方式來(lái)實(shí)現(xiàn):第一種是通過(guò)GPS定位拣技,第二種是網(wǎng)絡(luò)定位。GPS定位的工作原理是手機(jī)內(nèi)置的GPS硬件與衛(wèi)星交互來(lái)獲取經(jīng)緯度撒踪,這種定位方式精度準(zhǔn)確,但是只能在室外進(jìn)行大渤,室內(nèi)無(wú)法接收衛(wèi)星信號(hào)制妄。網(wǎng)絡(luò)定位的工作原理是根據(jù)手機(jī)當(dāng)前網(wǎng)絡(luò)附近的三個(gè)基站來(lái)進(jìn)行測(cè)速,計(jì)算手機(jī)之間的距離泵三,然后通過(guò)三角定位得到大概的位置耕捞,這種定位方式一般,室內(nèi)室外都可用烫幕。
??因?yàn)樘厥獾脑虬吵椋珿oogle雖然提供了相應(yīng)的API,但是國(guó)內(nèi)不可用较曼。所以我們一般借助第三方定位SDK來(lái)進(jìn)行定位:百度地圖磷斧,高德地圖。

1. 申請(qǐng)API Key

??在申請(qǐng)API Key之前捷犹,必須得注冊(cè)成為百度開(kāi)發(fā)者的賬號(hào)弛饭,這里就按照它的提示去做就好了,不描述了萍歉。在申請(qǐng)完成之后侣颂,訪(fǎng)問(wèn)這個(gè)http://lbsyun.baidu.com/apiconsole/key 地址。

申請(qǐng)key

因?yàn)檫@里沒(méi)有創(chuàng)建項(xiàng)目枪孩,所以空的憔晒。然后點(diǎn)擊創(chuàng)建應(yīng)用。應(yīng)用名稱(chēng),類(lèi)型入偷。然后按照自己的實(shí)際需要選擇服務(wù)印荔。

百度地圖創(chuàng)建應(yīng)用

下面這里有個(gè)SHA1,我們需要打開(kāi)Android Studio 的項(xiàng)目澎蛛,點(diǎn)擊右邊的Gradle->項(xiàng)目包名->Tasks->android->signingReport(雙擊)


雙擊signingReport后抚垄,就可以查看你的MD5和SHA1了,如果沒(méi)有出現(xiàn)谋逻,點(diǎn)一下這個(gè)/ab鍵呆馁。


這個(gè)就是我們需要的SHA1指紋,每個(gè)Android Studio 的指紋都不一樣毁兆,我們使用debug.keystore文件生成的指紋浙滤,這個(gè)是Android Studio自動(dòng)生成的用于測(cè)試的簽名文件。如果你需要正式發(fā)布的時(shí)候需要?jiǎng)?chuàng)建一個(gè)簽名文件气堕。要得到它的指紋可以這樣做: 在cmd中輸入:

keytool -list -v -keystore <簽名文件的路徑名>

使用Android Studio 生成簽名文件Build -> Generate signed APK文件纺腊。有的第一次可能會(huì)需要輸入操作系統(tǒng)的密碼,輸完了之后點(diǎn)擊OK就好了茎芭。進(jìn)入這個(gè)界面

選擇或者生成jks文件
  1. 選擇創(chuàng)建jks文件揖膜,并填寫(xiě)信息。填寫(xiě)信息的時(shí)候不要忘記密碼了梅桩,最好將上下兩個(gè)密碼設(shè)置一樣的壹粟,免得忘記。
創(chuàng)建jsk文件
選擇jks文件的目錄
創(chuàng)建jsk文件目錄
填寫(xiě)信息
  1. 創(chuàng)建完成之后宿百,會(huì)自動(dòng)保存你的key 和 value 趁仙,然后可能會(huì)需要輸入設(shè)置的密碼。
創(chuàng)建完成之后
輸入之前設(shè)置的密碼
  1. 可以打包apk了垦页。

  2. 接下來(lái)雀费,我們可以輸入之前的 keytool -list -v -keystore <簽名文件的路徑名>

正式發(fā)包的SHA1
  1. 最后回到百度地圖頁(yè)面,填上你想要的信息痊焊,點(diǎn)擊提交


    提交信息
  2. 最后你就可以回到http://lbsyun.baidu.com/apiconsole/key盏袄,刷新就可以出現(xiàn)你創(chuàng)建的應(yīng)用了。

刷新信息

這個(gè)udAn51qiTQY2XvxgDkBIR9ihq9hfKGj7就是你申請(qǐng)到的API Key薄啥。然后你就可以看是你的百度定位工作了貌矿。

2. 使用百度定位的準(zhǔn)備

  1. 在你申請(qǐng)好了API Key的時(shí)候,現(xiàn)在可以下載LBS的SDK包罪佳,下載地址:http: //lbsyun.baidu.com/sdk/download逛漫。選擇基礎(chǔ)定位和基礎(chǔ)地圖就可以了。
選擇sdk下載界面
  1. 在你選擇好了之后赘艳,下載壓縮包酌毡,解壓效果如下圖所示克握,然后將BaiduLBS_Android.jar包添加到Android Studio 中的libs中,然后右鍵單擊Add as Library,將其他的文件新建一個(gè)包放在src/main/jniLibs ,用于存放so文件枷踏。


    解壓包

3. 確定經(jīng)緯度

  1. 修改actiivty_main.xml,布局只有一個(gè)TextView控件菩暗,用于顯示當(dāng)前位置的經(jīng)緯度。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_postion"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
       />

</LinearLayout>

  1. 修改AndroidManifest.xml文件旭蠕,添加權(quán)限停团,配置API Key。
    主要是<meta-data>和<service>這兩個(gè)不能忽視掏熬。<meta-data>的name不用改佑稠,value改成你申請(qǐng)的API Key,service不用改動(dòng)。
<meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="AK" />

    <service android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote">

完整代碼:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.demo.bddemo">

    <!-- 這個(gè)權(quán)限用于進(jìn)行網(wǎng)絡(luò)定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!-- 這個(gè)權(quán)限用于訪(fǎng)問(wèn)GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!-- 用于訪(fǎng)問(wèn)wifi網(wǎng)絡(luò)信息旗芬,wifi信息會(huì)用于進(jìn)行網(wǎng)絡(luò)定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!-- 獲取運(yùn)營(yíng)商信息舌胶,用于支持提供運(yùn)營(yíng)商信息相關(guān)的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!-- 這個(gè)權(quán)限用于獲取wifi的獲取權(quán)限,wifi信息會(huì)用來(lái)進(jìn)行網(wǎng)絡(luò)定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!-- 用于讀取手機(jī)當(dāng)前的狀態(tài)-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!-- 寫(xiě)入擴(kuò)展存儲(chǔ)疮丛,向擴(kuò)展卡寫(xiě)入數(shù)據(jù)幔嫂,用于寫(xiě)入離線(xiàn)定位數(shù)據(jù)-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!-- 訪(fǎng)問(wèn)網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- SD卡讀取權(quán)限誊薄,用戶(hù)寫(xiě)入離線(xiàn)定位數(shù)據(jù)-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="udAn51qiTQY2XvxgDkBIR9ihq9hfKGj7" />
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote">
        </service>
    </application>

</manifest>
  1. 在MainActiivty文件中完成對(duì)地理定位的操作履恩,因?yàn)锳ndroid 6.0開(kāi)始,對(duì)權(quán)限要求的提高呢蔫,所以這里給了個(gè)刪減版的切心。方便好看。首先我們創(chuàng)建一個(gè)LocationClient實(shí)例咐刨,然后調(diào)用registerLocationListener()方法注冊(cè)定位監(jiān)聽(tīng)器昙衅。獲得地理位置信息之后扬霜,會(huì)返回一個(gè)BDLocation 對(duì)象定鸟。根據(jù)這個(gè)對(duì)象來(lái)獲取定位的信息。
public class MainActivity extends AppCompatActivity {

    private TextView tv_postion;
    private LocationClient mLocationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_postion = (TextView) findViewById(R.id.tv_postion);
        initLocation();
    }

    private void initLocation() {
        mLocationClient = new LocationClient(getApplicationContext());
        mLocationClient.registerLocationListener(new BDLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                StringBuilder  currentPosition =  new StringBuilder();
                currentPosition.append("維度:").append(bdLocation.getLatitude()).append("\n");
                currentPosition.append("經(jīng)度:").append(bdLocation.getLongitude()).append("\n");
                currentPosition.append("定位方式:");
                Log.e("tag","當(dāng)前的定位方式="+bdLocation.getLocType());

                if(bdLocation.getLocType() == BDLocation.TypeGpsLocation){
                     currentPosition.append("GPS");
                }else if(bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){
                    currentPosition.append("網(wǎng)絡(luò)");
                }
                tv_postion.setText(currentPosition);

            }
        });
    }
    mLocationClient.start();
}

添加權(quán)限版本的:

public class MainActivity extends AppCompatActivity {

    private TextView tv_postion;
    private LocationClient mLocationClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_postion = (TextView) findViewById(R.id.tv_postion);
        initLocation();
        List<String>  permissionList = new ArrayList<>();
        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE)!=PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if(!permissionList.isEmpty()){
            String[] permissions= permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this,permissions,1);
        }else{
            requestLocation();
        }

    }

    private void requestLocation() {
        mLocationClient.start();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length>0){
                    for (int result: grantResults
                         ) {
                        if(result !=PackageManager.PERMISSION_GRANTED){
                            Toast.makeText(this, "必須同意所有的權(quán)限才能使用本程序", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                }else{
                    Toast.makeText(this, "發(fā)生了錯(cuò)誤", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private void initLocation() {
        mLocationClient = new LocationClient(getApplicationContext());
        mLocationClient.registerLocationListener(new BDLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                StringBuilder  currentPosition =  new StringBuilder();
                currentPosition.append("維度:").append(bdLocation.getLatitude()).append("\n");
                currentPosition.append("經(jīng)度:").append(bdLocation.getLongitude()).append("\n");
                currentPosition.append("定位方式:");
                Log.e("tag","當(dāng)前的定位方式="+bdLocation.getLocType());

                if(bdLocation.getLocType() == BDLocation.TypeGpsLocation){
                     currentPosition.append("GPS");
                }else if(bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){
                    currentPosition.append("網(wǎng)絡(luò)");
                }
                tv_postion.setText(currentPosition);

            }
        });
//        mLocationClient.start();
    }

獲取error code:
public int getLocType ( )
返回值:
61 : GPS定位結(jié)果著瓶,GPS定位成功联予。
62 : 無(wú)法獲取有效定位依據(jù),定位失敗材原,請(qǐng)檢查運(yùn)營(yíng)商網(wǎng)絡(luò)或者wifi網(wǎng)絡(luò)是否正常開(kāi)啟沸久,嘗試重新請(qǐng)求定位。
63 : 網(wǎng)絡(luò)異常余蟹,沒(méi)有成功向服務(wù)器發(fā)起請(qǐng)求卷胯,請(qǐng)確認(rèn)當(dāng)前測(cè)試手機(jī)網(wǎng)絡(luò)是否通暢,嘗試重新請(qǐng)求定位威酒。
65 : 定位緩存的結(jié)果窑睁。
66 : 離線(xiàn)定位結(jié)果挺峡。通過(guò)requestOfflineLocaiton調(diào)用時(shí)對(duì)應(yīng)的返回結(jié)果。
67 : 離線(xiàn)定位失敗担钮。通過(guò)requestOfflineLocaiton調(diào)用時(shí)對(duì)應(yīng)的返回結(jié)果橱赠。
68 : 網(wǎng)絡(luò)連接失敗時(shí),查找本地離線(xiàn)定位時(shí)對(duì)應(yīng)的返回結(jié)果箫津。
161: 網(wǎng)絡(luò)定位結(jié)果狭姨,網(wǎng)絡(luò)定位定位成功。
162: 請(qǐng)求串密文解析失敗苏遥。
167: 服務(wù)端定位失敗饼拍,請(qǐng)您檢查是否禁用獲取位置信息權(quán)限,嘗試重新請(qǐng)求定位暖眼。
502: key參數(shù)錯(cuò)誤惕耕,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)KEY。
505: key不存在或者非法诫肠,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)KEY司澎。
601: key服務(wù)被開(kāi)發(fā)者自己禁用,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)KEY栋豫。
602: key mcode不匹配挤安,您的ak配置過(guò)程中安全碼設(shè)置有問(wèn)題,請(qǐng)確保:sha1正確丧鸯,“;”分號(hào)是英文狀態(tài)蛤铜;且包名是您當(dāng)前運(yùn)行應(yīng)用的包名,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)KEY丛肢。
501~700:key驗(yàn)證失敗围肥,請(qǐng)按照說(shuō)明文檔重新申請(qǐng)KEY。

建議使用真機(jī)測(cè)試蜂怎,模擬器測(cè)試容易出問(wèn)題穆刻。

模擬器測(cè)試結(jié)果
真機(jī)測(cè)試結(jié)果
  1. 但是我們?cè)趯?shí)際中的位置不可能會(huì)一直沒(méi)有變化的,而在默認(rèn)的情況下mLocationClient 的start()方法只會(huì)定位一次啊杠步。我們需要的是實(shí)時(shí)更新當(dāng)前的位置氢伟。所以修改代碼MainActivity.
public class MainActivity extends AppCompatActivity {
···

    private void requestLocation() {
        LocationClientOption  option = new LocationClientOption();
        option.setScanSpan(5000);
        mLocationClient.setLocOption(option);
        mLocationClient.start();
    }

···
   @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
    }

}

增加LocationClientOption 對(duì)象,然后調(diào)用setScanSpan()的方法來(lái)更新幽歼,這里設(shè)置5000朵锣,每5秒更新一次。這樣當(dāng)你的位置移動(dòng)的時(shí)候甸私,就可以實(shí)時(shí)更新經(jīng)緯度了诚些。

5.但是只給你一個(gè)經(jīng)緯度,你哪里知道你在哪里呢,你需要的是具體的地址

public class MainActivity extends AppCompatActivity {
···
 private void requestLocation() {
        LocationClientOption  option = new LocationClientOption();
        option.setScanSpan(5000);
        option.setIsNeedAddress(true);
        mLocationClient.setLocOption(option);
        mLocationClient.start();
    }

···
 private void initLocation() {
        mLocationClient = new LocationClient(getApplicationContext());
        mLocationClient.registerLocationListener(new BDLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                StringBuilder  currentPosition =  new StringBuilder();
                currentPosition.append("維度:").append(bdLocation.getLatitude()).append("\n");
                currentPosition.append("經(jīng)度:").append(bdLocation.getLongitude()).append("\n");
                currentPosition.append("國(guó)家:").append(bdLocation.getCountry()).append("\n");
                currentPosition.append("驶市汀:").append(bdLocation.getProvince()).append("\n");
                currentPosition.append("市:").append(bdLocation.getCity()).append("\n");
                currentPosition.append("區(qū):").append(bdLocation.getDistrict()).append("\n");
                currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");
                currentPosition.append("定位方式:");

                Log.e("tag","當(dāng)前的定位方式="+bdLocation.getLocType());

                if(bdLocation.getLocType() == BDLocation.TypeGpsLocation){
                     currentPosition.append("GPS");
                }else if(bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){
                    currentPosition.append("網(wǎng)絡(luò)");
                }
                tv_postion.setText(currentPosition);

            }
        });
//        mLocationClient.start();
    }



}
具體的經(jīng)緯度

定位結(jié)果選擇的方法

 //獲取定位結(jié)果
        location.getTime();    //獲取定位時(shí)間
        location.getLocationID();    //獲取定位唯一ID诬烹,v7.2版本新增助析,用于排查定位問(wèn)題
        location.getLocType();    //獲取定位類(lèi)型
        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();    //獲取街道碼(門(mén)牌號(hào))
        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)定位下椅您,獲取樓宇名稱(chēng)
        location.getFloor();    //室內(nèi)精準(zhǔn)定位下外冀,獲取當(dāng)前位置所處的樓層信息

4. 使用百度Map

在使用百度地圖之后,我們需要做的基本的功能就是在地圖上定位到自己當(dāng)前的位置掀泳。

  1. 修改activity_main.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
        android:id="@+id/tv_postion"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:text="Hello World!"
        android:visibility="gone"
       />
    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_bd"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        />

</LinearLayout>

  1. 修改MainActivity 文件雪隧,很簡(jiǎn)單的,首先調(diào)用SDKInitializer.initialize(getApplicationContext());來(lái)進(jìn)行初始化操作员舵,記得一定要在setContentView()之前脑沿,不然會(huì)出錯(cuò)。然后添加一個(gè)MapView马僻,重寫(xiě)onResume() ,onPauser()和onDestory()三個(gè)方法對(duì)MapView進(jìn)行管理庄拇。
public class MainActivity extends AppCompatActivity {

    private LocationClient mLocationClient;
    private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        mapView = (MapView) findViewById(R.id.map_bd);
      
      ```
}
 
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
     ···
        mapView.onDestroy();
     
    }
}

顯示地圖

但是這樣的地圖顯然不是我們想要的,我們需要的是可以直接定位到自己的當(dāng)前的位置韭邓,并在地圖上顯示我的位置措近。
??修改代碼MainActivity文件,然后根據(jù)百度SDK中提供的BaiduMap類(lèi)(地圖總控制器),調(diào)用MapView的getMap()方法來(lái)獲取BaiduMap的實(shí)例女淑。得到了BaiduMap的實(shí)例之后瞭郑,我們就可以對(duì)地圖進(jìn)行各種各樣的操作。
??因?yàn)槟J(rèn)顯示的地圖的位置是北京鸭你,所以我們想移動(dòng)到自己的當(dāng)前的位置并縮放大小怎么辦屈张?百度SDK中提供了LatLng 類(lèi)來(lái)獲取經(jīng)緯度。它的構(gòu)造方法接收兩個(gè)參數(shù)袱巨,一個(gè)緯度阁谆,一個(gè)經(jīng)度。再得到緯度和經(jīng)度之后愉老、我們想設(shè)置地圖的經(jīng)緯度和地圖场绿,需要用到MapStatus 類(lèi)通過(guò)MapStatus.Builder的方法設(shè)置經(jīng)緯度和地圖。最后將設(shè)置好的屬性裝載到BaiduMap里面

  LatLng  ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
  MapStatus.Builder builder = new MapStatus.Builder();
  builder.target(ll).zoom(18.0f); 
                baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

為了防止對(duì)此調(diào)用animateMapStatus這個(gè)變量俺夕,我們添加一個(gè)布爾值裳凸。

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

這只是完成了移動(dòng)到當(dāng)前的位置贱鄙,還沒(méi)有顯示我在地圖的位置呢劝贸。百度SDK中有個(gè)MyLocationData的類(lèi),這個(gè)類(lèi)封裝了設(shè)備當(dāng)前的地理位置逗宁。調(diào)用它的Build()方法映九,生成一個(gè)實(shí)例。

 MyLocationData.Builder  locationBuilder = new MyLocationData.Builder();
                    locationBuilder.latitude(bdLocation.getLatitude());
                    locationBuilder.longitude(bdLocation.getLongitude());
                    MyLocationData locationData = locationBuilder.build();
                    baiduMap.setMyLocationData(locationData);

完整的代碼:

public class MainActivity extends AppCompatActivity {

    private TextView tv_postion;
    private LocationClient mLocationClient;
    private MapView mapView;
    private BaiduMap baiduMap;
  private boolean  isFirstLocate = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        tv_postion = (TextView) findViewById(R.id.tv_postion);
        mapView = (MapView) findViewById(R.id.map_bd);
        baiduMap = mapView.getMap();
        baiduMap.setMyLocationEnabled(true);

        initLocation();
        initBaiDuMap();

        List<String>  permissionList = new ArrayList<>();
        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE)!=PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if(!permissionList.isEmpty()){
            String[] permissions= permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this,permissions,1);
        }else{
            requestLocation();
        }

    }

    private void initBaiDuMap() {



    }

    private void requestLocation() {

        LocationClientOption  option = new LocationClientOption();
        option.setScanSpan(5000);
        option.setIsNeedAddress(true);
        mLocationClient.setLocOption(option);
        mLocationClient.start();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length>0){
                    for (int result: grantResults
                         ) {
                        if(result !=PackageManager.PERMISSION_GRANTED){
                            Toast.makeText(this, "必須同意所有的權(quán)限才能使用本程序", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                }else{
                    Toast.makeText(this, "發(fā)生了錯(cuò)誤", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private void initLocation() {
        mLocationClient = new LocationClient(getApplicationContext());
        mLocationClient.registerLocationListener(new BDLocationListener() {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                StringBuilder  currentPosition =  new StringBuilder();
                currentPosition.append("維度:").append(bdLocation.getLatitude()).append("\n");
                currentPosition.append("經(jīng)度:").append(bdLocation.getLongitude()).append("\n");
                currentPosition.append("國(guó)家:").append(bdLocation.getCountry()).append("\n");
                currentPosition.append("氏箍拧:").append(bdLocation.getProvince()).append("\n");
                currentPosition.append("市:").append(bdLocation.getCity()).append("\n");
                currentPosition.append("區(qū):").append(bdLocation.getDistrict()).append("\n");
                currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");
                currentPosition.append("門(mén)牌號(hào):").append(bdLocation.getStreetNumber()).append("\n");
                currentPosition.append("定位方式:");


                if(bdLocation.getLocType() == BDLocation.TypeGpsLocation ||bdLocation.getLocType() == BDLocation.TypeNetWorkLocation){

                    if(isFirstLocate){
                        LatLng  ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
                        MapStatus.Builder builder = new MapStatus.Builder();
                        builder.target(ll).zoom(18.0f);
                        baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
                        isFirstLocate = false;
                    }
                    MyLocationData.Builder  locationBuilder = new MyLocationData.Builder();
                    locationBuilder.latitude(bdLocation.getLatitude());
                    locationBuilder.longitude(bdLocation.getLongitude());
                    MyLocationData locationData = locationBuilder.build();
                    baiduMap.setMyLocationData(locationData);

                }
//                tv_postion.setText(currentPosition);



            }
        });
//        mLocationClient.start();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
        mapView.onDestroy();
        baiduMap.setMyLocationEnabled(false);
    }
}
定位我的位置

這樣就可以完成想要的效果了件甥,寫(xiě)這一章的目的是為了方便講解一下百度地圖的基本用法捌议,具體的內(nèi)容還要看百度地圖的開(kāi)發(fā)文檔。

geihub地址:https://github.com/wangxin3119/BaiduDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末引有,一起剝皮案震驚了整個(gè)濱河市瓣颅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌譬正,老刑警劉巖宫补,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異曾我,居然都是意外死亡粉怕,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)抒巢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贫贝,“玉大人,你說(shuō)我怎么就攤上這事蛉谜≈赏恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵型诚,是天一觀(guān)的道長(zhǎng)蜈彼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)俺驶,這世上最難降的妖魔是什么幸逆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮暮现,結(jié)果婚禮上还绘,老公的妹妹穿的比我還像新娘。我一直安慰自己栖袋,他們只是感情好拍顷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著塘幅,像睡著了一般昔案。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上电媳,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天踏揣,我揣著相機(jī)與錄音,去河邊找鬼匾乓。 笑死捞稿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娱局,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼彰亥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了衰齐?” 一聲冷哼從身側(cè)響起任斋,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耻涛,沒(méi)想到半個(gè)月后仁卷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡犬第,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年锦积,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歉嗓。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰介,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鉴分,到底是詐尸還是另有隱情哮幢,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布志珍,位于F島的核電站橙垢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伦糯。R本人自食惡果不足惜柜某,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望敛纲。 院中可真熱鬧喂击,春花似錦、人聲如沸淤翔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旁壮。三九已至监嗜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抡谐,已是汗流浹背裁奇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留童叠,地道東北人框喳。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像厦坛,于是被迫代替她去往敵國(guó)和親五垮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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