Android 中定位方式基本能夠分爲兩種:GPS定位,網絡定位。php
GPS定位的工做原理是基於手機內置的GPS硬件直接和衛星進行交互來獲取當前的經緯度信息,這種方式的精確度很是高,可是缺點是隻能在室外使用,並且費電。html
網絡定位的工做原理是根據手機當前的網絡附近的三個基站進行測速,以此計算出手機和每一個基站之間的距離,再經過三角定位肯定出一個帶蓋的位置,這種方式優勢是在室內外均可以使用,可是精確度通常。java
百度地圖類參考:http://wiki.lbsyun.baidu.com/cms/androidsdk/doc/v4_4_1/index.html?overview-summary.htmlandroid
接下來,咱們將基於百度地圖SDK來開發。該SDK免費對外開發,且使用無次數限制。不過使用前須要申請祕鑰(AK)纔可使用。git
首先須要註冊一個百度帳號而後申請API Key, 申請地址: http://lbsyun.baidu.com/apiconsole/keyapi
Android 定位SDK 官方指南:http://lbsyun.baidu.com/index.php?title=android-locsdk網絡
建立應用:app
http://lbsyun.baidu.com/apiconsole/keyide
關於獲取SHA1:函數
(1) cd c:\Users\用戶名\.android (2) keytool -list -v -keystore debug.keystore (3)直接回車,不須要輸入密碼 (4)而後就能夠查看到 SHA1 注意這個SHA1爲開發版SHA1指紋
提交以後就能夠看到咱們申請到的AK了:
下載地址:http://lbsyun.baidu.com/sdk/download
選擇咱們須要的功能,而後點擊開發包開始下載
下載時候解壓,包文件下載到對應目錄下:
注意jniLibs目錄須要本身建立;
解壓後的 so 文件爲C/C++語言進行編寫,而後在用NDK 編譯出來的。
獲取當前位置信息官方文檔: http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/getloc
public class MainActivity extends AppCompatActivity { public LocationClient mLocationClient; private TextView tvPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); //註冊調用函數 tvPosition = (TextView) findViewById(R.id.activity_main_tv_position); /** * 運行時權限申請 */ List<String> permissionList = new ArrayList<>(); //存儲須要申請的全部權限 //GPS 定位信息 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); } //讀取手機當前狀態 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.READ_PHONE_STATE); } //讀寫外部存儲 if (ContextCompat.checkSelfPermission(MainActivity.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() { initLocation(); // 開始定位,回調結果會返回咱們註冊的監聽器中 MyLocationListener mLocationClient.start(); } private void initLocation(){ //LocationClientOption類,該類用來設置定位SDK的定位方式 LocationClientOption option=new LocationClientOption(); /**設置發起定位請求的時間間隔,默認0,即僅定位一次 */ option.setScanSpan(5000); //可選,默認高精度,設置定位模式,高精度,低功耗,僅設備 option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //可選,設置是否須要地址信息,默認不須要 option.setIsNeedAddress(true); //可選,默認false,設置是否使用gps option.setOpenGps(true); //可選,默認false,設置是否須要位置語義化結果,能夠在BDLocation.getLocationDescribe裏獲得,結果相似於「在北京天安門附近」 option.setIsNeedLocationDescribe(true); //可選,默認true,定位SDK內部是一個SERVICE,並放到了獨立進程,設置是否在stop的時候殺死這個進程,默認不殺死 option.setIgnoreKillProcess(false); mLocationClient.setLocOption(option); } @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, "必須贊成全部權限才能使用該程序", Toast.LENGTH_SHORT).show(); finish(); //退出程序 return; } } requestLocation(); //開始定位 }else { Toast.makeText(this, "發生未知錯誤", Toast.LENGTH_SHORT).show(); finish(); } break; } } @Override protected void onDestroy() { super.onDestroy(); mLocationClient.stop(); //活動銷燬後中止定位,減小電量消耗 } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation bdLocation) { StringBuilder currentPosition = new StringBuilder(); currentPosition.append("緯度:" + bdLocation.getLatitude() + "\n"); currentPosition.append("經度:" + bdLocation.getLongitude() + "\n"); currentPosition.append("定位方式:"); int locType= bdLocation.getLocType(); //獲取定位方式 if (locType== BDLocation.TypeGpsLocation) { currentPosition.append("GPS\n"); } else if (locType == BDLocation.TypeNetWorkLocation) { currentPosition.append("網絡\n"); } currentPosition.append("LocationDescribe:" + bdLocation.getLocationDescribe() + "\n"); currentPosition.append("Country:" + bdLocation.getCountry() + "\n"); currentPosition.append("Province:" + bdLocation.getProvince() + "\n"); currentPosition.append("City:" + bdLocation.getCity() + "\n"); currentPosition.append("District:" + bdLocation.getDistrict() + "\n"); currentPosition.append("Street:" + bdLocation.getStreet() + "\n"); currentPosition.append("StreetNumber:" + bdLocation.getStreetNumber() + "\n"); currentPosition.append("AddrStr:" + bdLocation.getAddrStr() + "\n"); tvPosition.setText(currentPosition); //顯示到界面當中 } } }
在地圖中顯示位置
首先地圖中添加 MapView控件
<com.baidu.mapapi.map.MapView android:id="@+id/activity_map_mapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true"/>
MapActivity :
public class MapActivity extends AppCompatActivity { public LocationClient mLocationClient; private MapView mapView; private BaiduMap baiduMap; private boolean isFirstLocate=true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_map); getSupportActionBar().hide();//隱藏ActionBar mapView=(MapView)findViewById(R.id.activity_map_mapView); baiduMap=mapView.getMap(); baiduMap.setMyLocationEnabled(true); //顯示當前設備位置 baiduMap.setCompassEnable(true); //是否顯示指南針 //baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);//衛星地圖 requestLocation(); } /** * 設置地圖顯示位置 */ private void navigateTo(BDLocation location){ if(isFirstLocate){ LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude()); //用於存放經緯度 MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(latLng); baiduMap.animateMapStatus(update); update =MapStatusUpdateFactory.zoomTo(16f); //設置縮放級別 baiduMap.animateMapStatus(update); isFirstLocate=false; } //顯示當前位置圖標 MyLocationData.Builder builder=new MyLocationData.Builder(); builder.latitude(location.getLatitude()); builder.longitude(location.getLongitude()); MyLocationData locationData=builder.build(); baiduMap.setMyLocationData(locationData); } /** * 開始定位 */ private void requestLocation() { initLocation(); // 開始定位,回調結果會返回咱們註冊的監聽器中 MyLocationListener mLocationClient.start(); } private void initLocation(){ //LocationClientOption類,該類用來設置定位SDK的定位方式 LocationClientOption option=new LocationClientOption(); /**設置發起定位請求的時間間隔,默認0,即僅定位一次 */ option.setScanSpan(5000); mLocationClient.setLocOption(option); } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } public class MyLocationListener implements BDLocationListener{ @Override public void onReceiveLocation(BDLocation bdLocation) { //若是已經定位成功 if(bdLocation.getLocType()==BDLocation.TypeGpsLocation ||bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){ navigateTo(bdLocation); } } } }