Android之3.5版的百度地圖的定位、覆蓋物實現以及覆蓋物的點擊事件
概述前段時間,在用到新版(3.5.0版)百度地圖時,在地圖覆蓋物實現以及覆蓋物點擊事件的添加部分遇到點挫折,發現網上很多的資料寫得都不夠詳細,所以我就想寫一個有關從地圖定位到地圖覆蓋物及其點擊事件的實現的博文。:覆蓋物及其點擊事件:
自訂縮放控制項的實現效果(注意圖中的加減按鈕):
實現此常式之前要做的的步驟:
1、申請Baidu API_KEY;
2、下載Baidu SDK,以及Baidu BS Sample,在libs中匯入baidumapapi_v3_5_0.jar和locSDK_6.11.jar兩個包
3、在main目錄下建立一個jniLibs檔案夾,匯入你解壓好的的Baidu sdk中so包中的arm64-v8a、armeabi、armeabi-v7a、x86、x86_64這幾個檔案夾,然後在Baidu BS中找到so庫arm64-v8a、armeabi、armeabi-v7a、mips、mips64、x86、x86_64,如果你下的是Baidu BS Sample,可以直接找個什麼功能都有的sample,把它的libs下的所有檔案拷貝到你的libs目錄下,這裡的每個so包的作用都不一樣,都導進去可以確保萬無一失,也可以在libs檔案夾下直接匯入上述的那些檔案夾幾個檔案夾。
註:我的jniLibs包的結構:
4、在AndroidManifest中添加許可權:
5、申明你的API KEY
你還可以在Baidu地圖官網上找到他們的API照著他們的步驟好好做一遍,把所有預備工作做好,然後直接看下面的Demo
Demo
public class BaiduMapActivity extends BaseActivity implements View.OnClickListener { private MapView mMapView; private BaiduMap mBaiduMap; private LocationClient mLocationClient = null; public BDLocationListener mBDListener = new MyLocationListener(); private List bdMapClientList; private double latitude; private double longitude; private boolean isFirstLocate = true; private Button mButtonAdd; private Button mButtonSub; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_baidu_map); /** * 縮放地圖的按鈕 */ mButtonAdd = (Button) findViewById(R.id.button_add); mButtonSub = (Button) findViewById(R.id.button_sub); mButtonAdd.setOnClickListener(this); mButtonSub.setOnClickListener(this); mMapView = (MapView) findViewById(R.id.mapView_client_raise); mMapView.showZoomControls(false);//讓百度地圖預設的地圖縮放控制項不顯示 mBaiduMap = mMapView.getMap(); mBaiduMap.setMyLocationEnabled(true);//使能百度地圖的定位功能 mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(mBDListener);//註冊地圖的監聽器 initLocation(); mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { final String info = (String) marker.getExtraInfo().get(info); InfoWindow infoWindow; //動態產生一個Button對象,使用者在地圖中顯示InfoWindow final Button textInfo = new Button(getApplicationContext()); textInfo.setBackgroundResource(R.drawable.locate_popup_state); textInfo.setPadding(10, 10, 10, 10); textInfo.setTextColor(Color.BLACK); textInfo.setTextSize(12); textInfo.setText(info); //得到點擊的覆蓋物的經緯度 LatLng ll = marker.getPosition(); textInfo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(BaiduMapActivity.this, 你點擊了+info, Toast.LENGTH_SHORT).show(); } }); //將marker所在的經緯度的資訊轉化成螢幕上的座標 Point p = mBaiduMap.getProjection().toScreenLocation(ll); p.y -= 90; LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p); //初始化infoWindow,最後那個參數表示顯示的位置相對於覆蓋物的豎直位移量,這裡也可以傳入一個監聽器 infoWindow = new InfoWindow(textInfo, llInfo, 0); mBaiduMap.showInfoWindow(infoWindow);//顯示此infoWindow //讓地圖以備點擊的覆蓋物為中心 MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.setMapStatus(status); return true; } }); //開始定位 mLocationClient.start(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_add: //放大地圖 mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomIn()); break; case R.id.button_sub: //縮小地圖 mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomOut()); break; default: break; } } /** * 自訂一個百度地圖的定位監聽器,可監聽定位類型,位置經緯度變化等一系列狀態 */ private class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation bdLocation) { latitude = bdLocation.getLatitude();//得到緯度 longitude = bdLocation.getLongitude();//得到經度 boolean isLocateFailed = false;//定位是否成功 if (isFirstLocate) { if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結果 ToastUtils.showToast(getApplicationContext(), GPS定位); } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {// 網路定位結果 ToastUtils.showToast(getApplicationContext(), 網路定位); } else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {// 離線定位結果 ToastUtils.showToast(getApplicationContext(), 離線定位); } else if (bdLocation.getLocType() == BDLocation.TypeServerError || bdLocation.getLocType() == BDLocation.TypeNetWorkException || bdLocation.getLocType() == BDLocation.TypeCriteriaException) { isLocateFailed = true; } /** * 如果定位不成功,顯示定位失敗的dialog */ if (isLocateFailed) { simpleDialog(); } initMapDataList(); addOverlay(); isFirstLocate = false; } } } /** * 添加覆蓋物的方法 */ private void addOverlay() { Marker marker = null; LatLng point = null; MarkerOptions option = null; BitmapDescriptor bitmap =BitmapDescriptorFactory.fromResource(R.mipmap.customer_location);; for (BDMapData data : bdMapClientList) { point = new LatLng(data.getLatitude(), data.getLongitude()); option = new MarkerOptions().position(point).icon(bitmap); marker = (Marker) mBaiduMap.addOverlay(option); //Bundle用於通訊 Bundle bundle = new Bundle(); bundle.putSerializable(info, data.getName()++緯度:+data.getLatitude()+ 經度:+data.getLongitude()); marker.setExtraInfo(bundle);//將bundle值傳入marker中,給baiduMap設定監聽時可以得到它 } //將地圖移動到最後一個標誌點 MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(point); mBaiduMap.setMapStatus(status); } /** * BaiduAPI上的常式,初始化定位 */ private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy );//可選,預設高精度,設定定位元模式,高精度,低功耗,僅裝置 option.setCoorType(bd09ll);//可選,預設gcj02,設定返回的定位結果座標系 int span = 1000; option.setScanSpan(span);//可選,預設0,即僅定位一次,設定發起定位請求的間隔需要大於等於1000ms才是有效 option.setIsNeedAddress(true);//可選,設定是否需要地址資訊,預設不需要 option.setOpenGps(true);//可選,預設false,設定是否使用gps option.setLocationNotify(true);//可選,預設false,設定是否當gps有效時按照1S1次頻率輸出GPS結果 option.setIsNeedLocationDescribe(true);//可選,預設false,設定是否需要位置語義化結果,可以在BDLocation.getLocationDescribe裡得到,結果類似於“在北京天安門附近” option.setIsNeedLocationPoiList(true);//可選,預設false,設定是否需要POI結果,可以在BDLocation.getPoiList裡得到 option.setIgnoreKillProcess(false);//可選,預設false,定位SDK內部是一個SERVICE,並放到了獨立進程,設定是否在stop的時候殺死這個進程,預設殺死 option.SetIgnoreCacheException(false);//可選,預設false,設定是否收集CRASH資訊,預設收集 option.setEnableSimulateGps(false);//可選,預設false,設定是否需要過濾gps模擬結果,預設需要 mLocationClient.setLocOption(option); } //初始化每個覆蓋物對應的資訊 private void initMapDataList() { bdMapClientList = new ArrayList<>(); //讓所有覆蓋物的經緯度與你自己的經緯度相近,以便開啟地圖就能看到那些覆蓋物 bdMapClientList.add(new BDMapData(中興創維, latitude - 0.0656, longitude - 0.00354)); bdMapClientList.add(new BDMapData(領卓科技, latitude + 0.024, longitude - 0.0105)); bdMapClientList.add(new BDMapData(藍翔駕校, latitude - 0.00052, longitude - 0.01086)); bdMapClientList.add(new BDMapData(優衣庫折扣店, latitude + 0.0124, longitude + 0.00184)); } /** * 定位失敗時顯示的dialog的初始化方法 */ public void simpleDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(BaiduMapActivity.this); builder.setMessage(當前網路不可用,請檢查網路設定) .setNeutralButton(確定, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); AlertDialog dialog = builder.create(); dialog.setCanceledOnTouchOutside(true); dialog.show(); }}
用於儲存覆蓋物資訊的類
public class BDMapData { private String name; private double latitude;//緯度 private double longitude;//經度 public BDMapData(String name, double latitude, double longitude) { this.name = name; this.latitude = latitude; this.longitude = longitude; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; }}
布局檔案activity_baidu_map:
不想貼源碼了。。。drawable檔案夾下內容:
item_bg.xml
add_state.xml
sub_state.xml:
locate_popup.xml
white:#ffffff
grey:#d0d0d0
mipmap中的圖片
customer_location.png:
add_group.png:
add_group_press.png:
btn_reduction_group.png:
btn_reduction_group_press.png:
btn_back_nZ喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcm1hbC5wbmc6PGltZyBhbHQ9"這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/151030/041K22337-8.png" title="\" />
總結:這裡只是實現了BaiduMap的最基本的幾個功能,它還有其它許多種功能,但都沒這個功能應用得頻繁,像什麼美團之類的應用裡就用到了覆蓋物,至於Baidu SDK別的很多功能,有瞭解的朋友可以寫個部落格給大家展示一下。