準備工做:java
1.申請百度地圖APIandroid
2.下載百度地圖的SDKgit
3.將SDK包中的BaiduLBS_Android.jar文件放到,項目裏的app/libs裏面api
4.在src/main目錄下建立一個名爲jniLibs的目錄,而後將SDK包中的其餘全部目錄放在裏面。數組
5.同步一下項目。網絡
首先修改佈局文件app
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/position_text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
用一個TextView控件用於顯示經緯度。ide
而後修改AndroidManifest.xml文件,代碼以下:佈局
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="co.example.leo.lbstest"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <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="N5yXI1cjwQXw631GaapHpD5Fdv43t8KW"/> <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:exported="true" android:process=":remote"> </service> </application> </manifest>
裏面添加了不少的權限,每個都是百度LBS SDK內部要用到的, 而後在<application>標籤內部添加了一個<meta -data>標籤。ui
這個標籤的androi:name部分是固定的,必須填寫com.baidu.lbsapi.API_KEY
android:value部分填入申請的APIKey。
最後還要對LBS SDK中的服務進行註冊。
最後修改MainActivity中的代碼。
1 import android.Manifest; 2 import android.content.pm.PackageManager; 3 import android.os.Bundle; 4 import android.support.annotation.NonNull; 5 import android.support.v4.app.ActivityCompat; 6 import android.support.v4.content.ContextCompat; 7 import android.support.v7.app.AppCompatActivity; 8 import android.widget.TextView; 9 import android.widget.Toast; 10 11 import com.baidu.location.BDLocation; 12 import com.baidu.location.BDLocationListener; 13 import com.baidu.location.LocationClient; 14 15 import java.util.ArrayList; 16 import java.util.List; 17 18 public class MainActivity extends AppCompatActivity { 19 20 public LocationClient mLocationClient; 21 private TextView positionText; 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 //建立一個LocationClient的實例,接受的context經過getApplicationContext()方法獲取。 27 mLocationClient = new LocationClient(getApplicationContext()); 28 //調用LocationClient的registerLocationListener()方法來註冊一個監聽器 當獲取到位置信息的時候,就會回調這個定位監聽器 29 mLocationClient.registerLocationListener(new MyLocationListener()); 30 setContentView(R.layout.activity_main); 31 32 positionText = (TextView)findViewById(R.id.position_text_view); 33 /* 34 * 以前在AndroidManifest.xml內聲明瞭不少權限。 35 * 其中有4個是危險權限。不過ACCESS_COARSE_LOCATION 和 ACCESS_FINE_LOCATION都屬於一個權限組,因此二者只須要申請其中一個就能夠了。 36 * 如何在運行時一次申請三個權限呢? 37 * 首先建立一個空的List集合,而後依次判斷這三個權限有沒有被受權,若是沒有受權就添加到List集合中,最後將List集合轉化成數組,在調用ActivityCompat.requestPermissions()方法就能夠一次性申請。 38 */ 39 List<String> permissionList = new ArrayList<>(); 40 if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){ 41 permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); 42 } 43 if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){ 44 permissionList.add(Manifest.permission.READ_PHONE_STATE); 45 } 46 if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ 47 permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 48 } 49 if(! permissionList.isEmpty()){ 50 String[] permissions = permissionList.toArray(new String[permissionList.size()]); 51 ActivityCompat.requestPermissions(this,permissions,1); 52 }else{ 53 requestLocation(); 54 } 55 } 56 57 private void requestLocation(){ 58 //調用start方法會回調到咱們註冊的監聽器上面 59 mLocationClient.start(); 60 } 61 62 @Override 63 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 64 switch (requestCode){ 65 case 1: 66 if(grantResults.length > 0){ 67 //將每一個申請的權限都進行判斷 若是存在一個沒有被受權,那麼就調用finish()方法關閉程序。 68 for(int result : grantResults){ 69 if(result != PackageManager.PERMISSION_GRANTED){ 70 Toast.makeText(MainActivity.this,"必須贊成全部權限才能使用本程序",Toast.LENGTH_SHORT).show(); 71 finish(); 72 return ; 73 } 74 } 75 //全部權限都已經受權,那麼直接調用requestLocation()方法開始定位。 76 requestLocation(); 77 }else{ 78 Toast.makeText(MainActivity.this,"發生未知錯誤", Toast.LENGTH_SHORT).show(); 79 finish(); 80 } 81 break; 82 default: break; 83 } 84 } 85 86 public class MyLocationListener implements BDLocationListener{ 87 @Override 88 public void onReceiveLocation(final BDLocation location) { 89 runOnUiThread(new Runnable() { 90 @Override 91 public void run() { 92 StringBuilder currentPosition = new StringBuilder(); 93 //經過BDLocation的getLatitude()方法獲取當前位置的緯度 94 currentPosition.append("緯度").append(location.getLatitude()).append("\n"); 95 //經過BDLocation的getLongitude()方法獲取當前位置的經度。 96 currentPosition.append("經線").append(location.getLongitude()).append("\n"); 97 //getLocType()方法獲取當前的定位方式。 98 if(location.getLocType() == BDLocation.TypeGpsLocation){ 99 currentPosition.append("GPS"); 100 }else if(location.getLocType() == BDLocation.TypeNetWorkLocation){ 101 currentPosition.append("網絡"); 102 } 103 positionText.setText(currentPosition); 104 } 105 }); 106 } 107 108 @Override 109 public void onConnectHotSpotMessage(String s, int i) { 110 111 } 112 } 113 }
默認狀況下,調用Location的start()方法只會定位一次。
若是想要實時更新當前的位置怎麼辦呢?
修改MainActivity中的代碼
1 private void requestLocation(){ 2 //調用start方法會回調到咱們註冊的監聽器上面 3 initLocation(); 4 mLocationClient.start(); 5 }
這裏在requestLocation()方法內增長了一個initLocation()方法
1 private void initLocation(){ 2 LocationClientOption option = new LocationClientOption(); 3 option.setScanSpan(5000); 4 mLocationClient.setLocOption(option); 5 }
在initLocation()方法中建立了一個LocationClientOption對象,而後調用它的setScanSpan()方法來設置更新的間隔。單位爲毫秒。
最後記得,在活動銷燬的時候要調用LocationClient的Stop()方法來中止定位。
1 @Override 2 protected void onDestroy(){ 3 super.onDestroy(); 4 mLocationClient.stop(); 5 }
選擇定位模式
定位模式有三種:
高精確度:容許使用GPS,無線網絡,藍牙或者移動網絡來進行定位。
節電:僅容許使用WLAN,藍牙或移動網絡肯定位置。
僅限設備:僅限GPS來進行定位。
也就是說,若是要想使用GPS定位功能,那麼必需要選擇高精確度模式,或者是僅限設備模式。
咱們能夠在以前的initLocation()方法中對百度LBS SDK的定位模式進行指定。
一共有三種模式可選:High_Accuracy,Battery_Saving,和Device_Sensors。
Hight_Accuracy表示高精確度模式,會在GPS信號正常的狀況下優先使用GPS定位。
Device_Sensors表示傳感器模式,只會用GPS進行定位。
High_Accuracy是默認的模式。
修改initLocation()中的代碼
1 private void initLocation(){ 2 LocationClientOption option = new LocationClientOption(); 3 option.setScanSpan(5000); 4 option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors); 5 mLocationClient.setLocOption(option); 6 }
這裏調用了setLocationMode()方法將定位模式指定成傳感器模式,也就是說只能用GPS進行定位。
看的懂的位置信息
咱們能夠經過一些簡單的接口調用就能獲得當前位置各類豐富的地址信息。
修改MainActivity中的initLocation()方法
1 private void initLocation(){ 2 LocationClientOption option = new LocationClientOption(); 3 option.setScanSpan(5000); 4 option.setIsNeedAddress(true); 5 mLocationClient.setLocOption(option); 6 }
這裏調用了LocationClientOption的setIsNeedAddress()方法,並傳入了true。這就表示咱們須要獲取當前位置的詳細的地址信息。
而後修改MainActivity中的MyLocationListener
1 public class MyLocationListener implements BDLocationListener{ 2 @Override 3 public void onReceiveLocation(final BDLocation location) { 4 runOnUiThread(new Runnable() { 5 @Override 6 public void run() { 7 StringBuilder currentPosition = new StringBuilder(); 8 //經過BDLocation的getLatitude()方法獲取當前位置的緯度 9 currentPosition.append("緯度").append(location.getLatitude()).append("\n"); 10 //經過BDLocation的getLongitude()方法獲取當前位置的經度。 11 currentPosition.append("經線").append(location.getLongitude()).append("\n"); 12 currentPosition.append("國家").append(location.getCountry()).append("\n"); 13 currentPosition.append("省").append(location.getProvince()).append("\n"); 14 currentPosition.append("市").append(location.getCity()).append("\n"); 15 currentPosition.append("區").append(location.getDistrict()).append("\n"); 16 currentPosition.append("街道").append(location.getStreet()).append("\n"); 17 //getLocType()方法獲取當前的定位方式。 18 if(location.getLocType() == BDLocation.TypeGpsLocation){ 19 currentPosition.append("GPS"); 20 }else if(location.getLocType() == BDLocation.TypeNetWorkLocation){ 21 currentPosition.append("網絡"); 22 } 23 positionText.setText(currentPosition); 24 } 25 }); 26 }
getCounty()獲取當前所在國家
getProvince()獲取當前所在省
以此類推。
須要咱們注意的是獲取地址信息必定須要用到網絡,所以即便咱們將定位模式指定成了Device Sensors,也會自動開啓網絡定位功能。
讓「我」顯示在地圖上
百度LBS SDK當中提供了一個MyLocatioData.Builder類,這個類是用來封裝設備當前所在位置的。只須要將經緯度信息傳入到這個類的相應方法中就能夠了。以下所示:
MyLocationData.Builder locationBuilder = new MyLocationData.Builder(); locationBuilder.latitude(39.315); locationBuilder.longitude(116.404);
MyLocationData.Builder類中還提供了一個builde()方法,當咱們把要封裝的信息都設置完成以後,只須要調用它的build()方法。就會生成一個MyLocationData的實例。
而後將這個實例傳入到BaiduMap的setMyLocationData()方法中,就可讓設備當前的位置顯示在地圖上了。