android百度地图自动定位
最近一直在研究百度地圖方面的項(xiàng)目,第一次接觸,多多少少有些不知所措,因此,掉坑是經(jīng)常的事,用我們猿人的話說,經(jīng)常跳坑的猿人才是真正的猿人(出自個(gè)人,嘻嘻),所以,掉坑不是壞事,而是咱們猿人掌握知識(shí)的必不可少的部分。雖然,掉坑正常,但是重復(fù)掉同樣的坑就有點(diǎn)。。。。。。所以,猿人還有一個(gè)最重要的特質(zhì)就是善于總結(jié),得出自己套路,這樣才會(huì)避免每次都會(huì)在同一地點(diǎn)摔跤。。。。。。
上面說到了研究百度地圖方面的項(xiàng)目,在閑暇之余呢,我就想自己實(shí)現(xiàn)一個(gè)簡單的定位功能,經(jīng)過短時(shí)間的代碼實(shí)現(xiàn),發(fā)現(xiàn)并沒有實(shí)現(xiàn)定位功能,經(jīng)過debugger發(fā)現(xiàn),provider一直為null,然后各種百度啊,查看百度地圖API啊,并沒有得與解決,然后我就一直梳理整個(gè)思路,最終把問題定位在權(quán)限這塊,最終才得以解決。所以,在這我也想吧我經(jīng)歷的這個(gè)坑給記錄下來,給大家分享分享。(由于剛接觸,道行還不深,真知灼見,還望海涵)。
說到,集成百度地圖,那就離不開百度地圖SDK,怎么申請百度的API_KEY在這就不多說了,度娘那一大推。。。。。但是申請完API_KEY只后一定得記住,不過不記住也沒關(guān)系,在百度地圖開發(fā)者中心能查看的到。
開始吧。。。。。。
一、添加jar包,百度地圖SDK和百度定位SDK的jar拷貝到工程的libs中
二、在清單文件中添加permission(權(quán)限)
三、將申請的百度地圖API_KEY添加到清單文件中
四、在清單文件中注冊定位服務(wù)service
五、布局文件
六、MainActivity代碼
(1)控件的初始化
(2)首先應(yīng)該檢測gps是否正常,如果設(shè)備的gps沒開啟,需提示用戶開啟
(3)通過系統(tǒng)系統(tǒng)的Criteria類選擇合適的地理位置和設(shè)置只要展示的數(shù)據(jù)類型,以下是最常用的幾種類型:
具體的方法如下:
此時(shí)程序會(huì)報(bào)錯(cuò),報(bào)錯(cuò)的地方就是在調(diào)用getLastKnownLocation()方法時(shí),因?yàn)榇藭r(shí)是在訪問系統(tǒng)的東西,系統(tǒng)內(nèi)的東西的權(quán)限使用是相當(dāng)嚴(yán)格的,所以,我們需要在此處check permission,判斷一下權(quán)限或者try…catch…一下
如果不這樣,系統(tǒng)會(huì)啟動(dòng)安全保護(hù)(SecurityException),不會(huì)執(zhí)行獲取GPS信息,此時(shí)的provider一直是null的,再繼續(xù)。。。。。
(4)實(shí)現(xiàn)對位置移動(dòng)的監(jiān)聽,監(jiān)聽內(nèi)需實(shí)現(xiàn)locationListener的四個(gè)方法,分別是紅色區(qū)域內(nèi)圈出的。。。。。
(5)實(shí)現(xiàn)定位的方法,并且改變地圖展示的層級(jí)
由于GPS返回回來的坐標(biāo)是沒有經(jīng)過處理的,所以需要轉(zhuǎn)換成百度地圖一直的坐標(biāo),按理說需要Gis的換算才能與百度地圖吻合上,這就有點(diǎn)麻煩了,對Gis不了解的猿人肯定是一臉懵逼,不知如何下手啊,干著急啊,,,,就度娘啊,還是一臉懵逼啊,其實(shí)很多朋友都忽略了一點(diǎn),就是百度地圖API,他既然能提供SDK,那么這塊的基本轉(zhuǎn)換的接口肯定是有的,果不其然,官方API文檔提供了自動(dòng)轉(zhuǎn)換的類,如下:
因此在定位的方法內(nèi),先將GPS返回的的經(jīng)緯度進(jìn)行轉(zhuǎn)換,加上以上3行代碼,輕輕松松解決了。。。。。
此時(shí)本應(yīng)該可以完事的,但是在Android6.0之后的設(shè)備運(yùn)行會(huì)出問題,別忘了添加運(yùn)行時(shí)權(quán)限,因此還需加上一下代碼
最后在oncreat()方法內(nèi)調(diào)用requestPermissions()方法,即可,requestPermissions()在哪調(diào)用這是關(guān)鍵,這是第一個(gè)坑,當(dāng)時(shí)我不是在oncreate()內(nèi)調(diào)用的,在調(diào)試的時(shí)候一直不會(huì)定位,可把我給愁的
那么第二個(gè)坑接著就來了,咱們在位置發(fā)生變化時(shí)需要調(diào)用以下方法
那么當(dāng)緊接著移動(dòng)的時(shí)候,上一次的對象應(yīng)該移除掉,因此需要在監(jiān)聽內(nèi)執(zhí)行remove操作,這一點(diǎn)很多朋友會(huì)忽視
至此,整個(gè)自動(dòng)定位的功能的實(shí)現(xiàn)和我所遇到的坑都描述完了,寫得不是很好,但是還是希望能幫助到大家,歡迎大家指正!!!謝謝
import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.widget.Toast;import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.MapStatusUpdate; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.model.LatLng; import com.baidu.mapapi.utils.CoordinateConverter;public class MainActivity extends AppCompatActivity {private MapView mapView;private BaiduMap aMap;private boolean isFirstLocate = true;private LocationManager locationManager;private String provider;// 權(quán)限請求碼private final int REQUEST_CODE = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SDKInitializer.initialize(getApplicationContext());setContentView(R.layout.activity_main);initView();requestPermissions();locationManager = (LocationManager) MainActivity.this.getSystemService(Context.LOCATION_SERVICE);openGPSSetting();getLocation();}private void initView() {mapView = (MapView) findViewById(R.id.mapView);aMap = mapView.getMap();// 開啟交通圖aMap.setTrafficEnabled(true); // 設(shè)置地圖展示的方式:衛(wèi)星地圖等aMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);}//定位private void navigateTo(Location location) {if (isFirstLocate) {LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());// 將google地圖、soso地圖、aliyun地圖、mapabc地圖和amap地圖// 所用坐標(biāo)轉(zhuǎn)換成百度坐標(biāo)CoordinateConverter converter = new CoordinateConverter();converter.from(CoordinateConverter.CoordType.COMMON);//sourceLatLng待轉(zhuǎn)換坐標(biāo)converter.coord(ll);LatLng desLatLng = converter.convert();MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(desLatLng);aMap.animateMapStatus(update);update = MapStatusUpdateFactory.zoomTo(17f);aMap.animateMapStatus(update);isFirstLocate = false;}}//檢測gps模塊是否正常private void openGPSSetting() {if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {Toast.makeText(this, "GPS模塊正常", Toast.LENGTH_SHORT).show();return;}Toast.makeText(this, "請開啟GPS!", Toast.LENGTH_SHORT).show();// 跳轉(zhuǎn)到GPS的設(shè)置頁面Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);startActivityForResult(intent, 0); // 此為設(shè)置完成后返回到獲取界面}private void getLocation() {// android通過criteria選擇合適的地理位置服務(wù)Criteria criteria = new Criteria();criteria.setAccuracy(Criteria.ACCURACY_FINE);// 高精度criteria.setAltitudeRequired(false);// 設(shè)置不需要獲取海拔方向數(shù)據(jù)criteria.setBearingRequired(false);// 設(shè)置不需要獲取方位數(shù)據(jù)criteria.setCostAllowed(false);// 設(shè)置允許產(chǎn)生資費(fèi)criteria.setPowerRequirement(Criteria.POWER_LOW);// 低功耗provider = locationManager.getBestProvider(criteria, true);// 獲取GPS信息requestPermissions();if (ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) !=PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling// ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding// public void onRequestPermissionsResult(int requestCode, String[] permissions,// int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}Location location = locationManager.getLastKnownLocation(provider);// 通過GPS獲取位置updateUIToNewLocation(location); // 設(shè)置監(jiān)聽器,自動(dòng)更新的最小時(shí)間為間隔N秒(這里的單位是微秒)或最小位移變化超過N米(這里的單位是米)locationManager.requestLocationUpdates(provider, 1 * 1000, 0.00001F,locationListener);}private void updateUIToNewLocation(Location location) {if (location != null) {navigateTo(location);Toast.makeText(this, "緯度" + location.getLatitude(), Toast.LENGTH_SHORT).show();Toast.makeText(this, "經(jīng)度" + location.getLongitude(), Toast.LENGTH_SHORT).show();// Location類的方法:// getAccuracy():精度(ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION)// getAltitude():海撥// getBearing():方位,行動(dòng)方向// getLatitude():緯度// getLongitude():經(jīng)度// getProvider():位置提供者(GPS/NETWORK)// getSpeed():速度// getTime():時(shí)刻} else {Toast.makeText(this, "無法獲取地理信息", Toast.LENGTH_SHORT).show();}}//// 定義對位置變化的監(jiān)聽函數(shù)LocationListener locationListener = new LocationListener() {public void onLocationChanged(Location location) {if (location != null) {navigateTo(location);}if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling// ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding// public void onRequestPermissionsResult(int requestCode, String[] permissions,// int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}locationManager.removeUpdates(this); // locationManager.setTestProviderEnabled(provider, false);}public void onStatusChanged(String provider, int status, Bundle extras) {}public void onProviderEnabled(String provider) {}public void onProviderDisabled(String provider) {}};private void requestPermissions() {if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {// 申請權(quán)限ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);}}// 請求運(yùn)行時(shí)權(quán)限的回調(diào)方法// requestCode:用于識(shí)別申請權(quán)限的請求碼// permissions:請求的權(quán)限// grantResults:對應(yīng)權(quán)限的請求結(jié)果@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);switch (requestCode) {case REQUEST_CODE:if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 允許權(quán)限Toast.makeText(MainActivity.this, "允許權(quán)限", Toast.LENGTH_SHORT).show();} else {// 拒絕權(quán)限Toast.makeText(MainActivity.this, "拒絕權(quán)限", Toast.LENGTH_SHORT).show();}break;}}}總結(jié)
以上是生活随笔為你收集整理的android百度地图自动定位的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV4.5.2(+opencv_
- 下一篇: android:layout_gravi