Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!...
Android高效率編碼-第三方SDK詳解系列(一)——百度地圖,繪制,覆蓋物,導航,定位,細膩分解!
這是一個系列,但是我也不確定具體會更新多少期,最近很忙,主要還是效率的問題,所以一些有效的東西還是會及時更新的,比如后續會出
- 分享SDK:sharesdk
- 后端SDK:Bmob
- 推送SDK:極光推送
- 短信SDK:驗證碼實現
- 等等……
或者出一些裝ubuntu系統或者黑蘋果教程什么的,或者5.X之后的新玩法,主要還是困于時間方面缺少,或許這也是一種鍛煉吧,工作了挺久的了,越發覺得自己的JAVA基礎實在是爛的可以,想去買一本JAVA的書籍啃一啃,剛好年假也有15天,這都是后話了,我們言歸正傳,今天分析的是百度地圖的sdk怎么去使用,包括他的幾個類的詳細說明,可能寫得快的話半個禮拜就寫完了就會加上高德地圖什么的,不過看現在公司項目的樣子,一天能寫一個小時就不錯了
一.百度API
百度地圖API:http://developer.baidu.com/map/
二.搭建地圖環境
1.申請百度地圖的key 2.下載對應功能的sdk 3.新建一個工程導入sdk到lib里面
1.申請KEY
**我們打開百度API官網-開發-Android SDK**
然后選擇獲取密鑰
創建應用
我們在IDE里創建一個工程–BaiDuMapDemo
然后依次填入所需要的信息
這里很多人對這個SHA1值很疑問,那我先科普一下這個是什么玩意吧
什么是SHA1?
安全哈希算法(Secure Hash Algorithm)主要適用于數字簽名標準 (Digital Signature Standard DSS)里面定義的數字簽名算法(Digital Signature Algorithm DSA)。對于長度小于2^64位的消息,SHA1會產生一個160位的消息摘要。當接收到消息的時候,這個消息摘要可以用來驗證數據的完整性。在傳輸的過程中,數據很可能會發生變化,那么這時候就會產生不同的消息摘要。 SHA1有如下特性:不可以從消息摘要中復原信息;兩個不同的消息不會產生同樣的消息摘要。
那我們該如何去獲取呢?
Eclipse獲取方法
Android Studio獲取方法
借鑒博文:http://blog.csdn.net/kezhongke/article/details/42678077
好了,這里注意一下,這里我用com.lgl.baidumapdemo這個包名官方提示我敏感詞,所以我換了一個,本質上是沒有任何影響的,不用糾結,當我們提交之后,就可以獲取到key了2.下載SDK
我想我不用多說什么的,這里需要自定義下載,也就是說你需要什么功能你就選擇什么功能,這里做demo的話全部下載了,這里也不提供下載了,你們可以自己去下載,我把地址給出來吧:SDK下載地址:http://developer.baidu.com/map/index.php?title=androidsdk/sdkandev-download
3.配置工程
首先我們把下載的sdk全部放在lib庫里面,有點多,畢竟百度地圖的功能還是可以的,不過會顯得很臃腫,建議需要什么功能就放哪個架包吧,下載的時候我相關的demo和文檔說明的Eclipse
1. 在Eclipse 中選中工程,右鍵選 Properties->Java Build Path->Order and Export 使 Android Private Libraries處于勾選狀態;2. Project -> clean-> clean allAndroid Studio
第一步:在工程app/libs目錄下放入baidumapapi_vX_X_X.jar包,在src/main/目錄下新建jniLibs目錄,放入libBaiduMapSDK_vX_X_X_X.so如下圖所示,注意jar和so的前3位版本號必須一致,并且保證使用一次下載的文件夾中的兩個文件,不能不同功能組件的jar或so交叉使用。第二步:導入jar包。菜單欄選擇File->Project Structor->Modules->Dependencies,點擊+號,選擇File dependency,選擇jar包導入。 通過以上兩步操作后,您就可以正常使用百度地圖SDK為您提供的全部功能了。三,HelloMap
1.權限
權限是必備的,而且說明文檔里也十分詳細的說明了 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.GET_TASKS" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_SETTINGS" />2.配置KEY
在application中添加開發密鑰 <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="開發者 key" />3.布局
在布局中直接添加 <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" />4.初始化
在應用程序創建時初始化 SDK引用的Context 全局變量: 記住,一定要再setContentView之前執行 并且初始化mapview public class MainActivity extends Activity { private MapView mMapView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在使用SDK各組件之前初始化context信息,傳入ApplicationContext //注意該方法要再setContentView方法之前實現 SDKInitializer.initialize(getApplicationContext()); mMapView = (MapView) findViewById(R.id.bmapView); } }5.地圖的生命周期
前期工作我們都準備完成了,現在我們就把百度地圖的生命周期給添加上 @Overrideprotected void onDestroy() {super.onDestroy();// 在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命周期管理mMapView.onDestroy();}@Overrideprotected void onResume() {super.onResume();// 在activity執行onResume時執行mMapView. onResume (),實現地圖生命周期管理mMapView.onResume();}@Overrideprotected void onPause() {super.onPause();// 在activity執行onPause時執行mMapView. onPause (),實現地圖生命周期管理mMapView.onPause();}好了,準備了這么久,現在我們可以見證奇跡的時刻了
截圖
好的,我們的初級教程到這里了,下面,就是一些高級的玩法了
四.地圖進階——基本控制
1.核心類
//三大核心類 1.BMapManager//百度地圖管理工具 2.MapView //地圖控件——MapView的MKMapViewListener //控件的點擊事件 3.MapController //地圖控制,必須MapViewy已經存在//控制地圖平移,縮放,選擇等..2.授權驗證
我們做這種類型的應用,一般也就兩個交互,一個就是key的授權,還有一個就是網絡的授權了,我們我們在開始實現地圖功能之前應該先去判斷一下這兩個條件是否實現了實現廣播機制
其實就是寫個小廣播,不需要很多代碼 //初始化一個廣播 private MyBroadcastReceiver receiver; class MyBroadcastReceiver extends BroadcastReceiver {//實現一個廣播@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();// 網絡錯誤if (action.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {Toast.makeText(MainActivity.this, "無法連接網絡", Toast.LENGTH_SHORT).show();// key效驗失敗} else if(action.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {Toast.makeText(MainActivity.this, "百度地圖key效驗失敗",Toast.LENGTH_SHORT).show();}}} //在onCreate()方法中注冊廣播receiver = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();// 網絡錯誤filter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);// 效驗key失敗filter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);registerReceiver(receiver, filter); //注意要在onDestroy()方法中銷毀這個廣播unregisterReceiver(receiver);廣播寫好了,我們來說一下這兩條廣播吧
邏輯就是當進入應用的時候sdk會去驗證這兩個條件,如果發現網絡錯誤或者驗證Key失敗就會發送一條廣播,廣播接收者接收到了這條廣播之后彈出一個Toast,當然,你如果想人性化一點也可以彈一個Dialog,這里作為demo就不做這么復雜的東西了 //網絡錯誤SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR//key效驗失敗SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR3.設置地圖縮放級別
雖然地圖上是有按鈕可以進行縮放的,但是再某些場景還是需要我們人工縮放,但是再縮放之前,我們應該先來了解一下縮放級別 縮放級別在2.X是個分水嶺,在2.X之前的級別是(3-18),之后是(3-19),主要是有兩個區別 1.修改了文件格式,具體是啥也不需要懂,只要知道,比如深圳的地圖100M,2.x之后只要15M左右就行了 2.增加了3D效果,這要在18或者19的級別上才可以看到 我們先把BaiduMap給實現了 private BaiduMap mBaiduMap; //在onCreate()中 mBaiduMap = mMapView.getMap(); 然后我們寫一個方法讓onCreate()調用 private void init(){//描述地圖將要發生的變化,使用工廠類MapStatusUpdateFactory創建,設置級別//為18,進去就是18了,默認是12MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(18); mBaiduMap.setMapStatus(mapStatusUpdate);//是否顯示縮放按鈕//mMapView.showZoomControls(false);}4.設置中心點(定位的初級實現)
你有沒有發現,我們一進去地圖顯示的是北京天安門,其實這個就叫中心點,我們可以更改這個中心點 同樣的,我們寫一個方法在onCreate()中調用 private void init(){//經緯度(緯度,經度) 我們這里設置深圳世界之窗的位置LatLng latlng = new LatLng(22.5422870000,113.9804440000);MapStatusUpdate mapStatusUpdate_circle = MapStatusUpdateFactory.newLatLng(latlng);mBaiduMap.setMapStatus(mapStatusUpdate_circle);}截圖
現在一進去中心點就會在世界之窗的坐標點了,我們定位的實現不就是獲取到坐標點然后顯示嘛!嘿嘿!5.地圖控制器(旋轉,移動,縮放)
模擬點擊 模擬器上運行按12345鍵實現,當然,你寫Button的點擊事件也可以 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1://放大縮放級別,每次放大一個級別MapStatusUpdate bigStatus = MapStatusUpdateFactory.zoomIn();mBaiduMap.setMapStatus(bigStatus);break;case KeyEvent.KEYCODE_2://縮小縮放級別,每次縮小一個級別MapStatusUpdate smallStatus = MapStatusUpdateFactory.zoomOut();mBaiduMap.setMapStatus(smallStatus);break;case KeyEvent.KEYCODE_3://以屏幕中心點旋轉MapStatus mapStatus = mBaiduMap.getMapStatus(); //獲取當前地圖的狀態float rotate = mapStatus.rotate; //獲取旋轉角度Log.i("旋轉角度", "rotate"+rotate);//用獲取到的當前角度+30就是每次都旋轉30° 范圍0-360°MapStatus rotates =new MapStatus.Builder().rotate(rotate+30).build();//更新地圖的選擇MapStatusUpdate rotateStatus = MapStatusUpdateFactory.newMapStatus(rotates);mBaiduMap.setMapStatus(rotateStatus);break;case KeyEvent.KEYCODE_4://以立體方式旋轉MapStatus mapStatusOver = mBaiduMap.getMapStatus(); //獲取當前地圖的狀態float overlook = mapStatusOver.overlook; //獲取旋轉角度Log.i("旋轉角度", "overlook"+overlook);//弧角范圍:0-45°MapStatus overlooks =new MapStatus.Builder().overlook(overlook-5).build();MapStatusUpdate overlookStatus = MapStatusUpdateFactory.newMapStatus(overlooks);mBaiduMap.setMapStatus(overlookStatus);break;case KeyEvent.KEYCODE_5://移動MapStatusUpdate moveStatus = MapStatusUpdateFactory.newLatLng(new LatLng(22.5422870000, 113.9804440000));//帶動畫更新狀態 默認300msmBaiduMap.animateMapStatus(moveStatus);break;}6.指南針
//顯示指南針 mBaiduMap.getUiSettings().setCompassEnabled(true); //顯示位置 mBaiduMap.getUiSettings().setCompassPosition(new Point(x, y));7.地圖事件
不是很常用,地圖本身都是自帶點擊事件的 //設置地圖單擊監聽 mBaiduMap.setOnMapClickListener(new OnMapClickListener() {@Overridepublic boolean onMapPoiClick(MapPoi arg0) {// TODO Auto-generated method stubreturn false;}@Overridepublic void onMapClick(LatLng arg0) {// TODO Auto-generated method stub}}); //覆蓋物點擊事件 mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker arg0) {// TODO Auto-generated method stubreturn false;}}); //設置地圖雙擊監聽 mBaiduMap.setOnMapDoubleClickListener(new OnMapDoubleClickListener() {@Overridepublic void onMapDoubleClick(LatLng arg0) {// TODO Auto-generated method stub}}); //發起截圖請求 mBaiduMap.snapshot(new SnapshotReadyCallback() {@Overridepublic void onSnapshotReady(Bitmap arg0) {// TODO Auto-generated method stub}});五.地圖高階——圖層
1.什么是圖層
一個地圖是由很多個圖層包裹的,還有級別,這是由圖塊決定的,你所看到的房子,學校什么的都是由圖層實現的2.圖層分類
底圖
基本的一個地圖包括了各種建筑啥啥啥的實時交通圖
交通路況啥啥啥的衛星圖
就是從衛星上拍下來的嘛,哈哈哈哈,這些都一筆帶過吧其他
還有各種各樣的,比如熱力圖啥的3.覆蓋物
覆蓋物的層級壓蓋關系,如下(從上往下) 1、基礎底圖(包括底圖、底圖道路、衛星圖等); 2、地形圖圖層(GroundOverlay); 3、熱力圖圖層(HeatMap); 4、實時路況圖圖層(BaiduMap.setTrafficEnabled(true);); 5、百度城市熱力圖(BaiduMap.setBaiduHeatMapEnabled(true);); 6、底圖標注(指的是底圖上面自帶的那些POI元素); 7、幾何圖形圖層(點、折線、弧線、圓、多邊形); 8、標注圖層(Marker),文字繪制圖層(Text); 9、指南針圖層(當地圖發生旋轉和視角變化時,默認出現在左上角的指南針); 10、定位圖層(BaiduMap.setMyLocationEnabled(true);); 11、彈出窗圖層(InfoWindow); 12、自定義View(MapView.addView(View););4.基礎圖層切換
我們還是模擬操作,你也可以用Button點擊事件去實現,這里就直接在onKeyDown()里面迷你按123鍵進行操作 //點擊屏幕切換圖層 從地圖-衛星圖-交通圖@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {// 底圖case KeyEvent.KEYCODE_1:// 設置地圖類型mBaiduMap.setMapType(mBaiduMap.MAP_TYPE_NORMAL);break;// 衛星圖case KeyEvent.KEYCODE_2:mBaiduMap.setMapType(mBaiduMap.MAP_TYPE_SATELLITE);break;// 交通圖case KeyEvent.KEYCODE_3:// 交通圖是否打開mBaiduMap.setTrafficEnabled(true);break;}return super.onKeyDown(keyCode, event);}5.免費申請標注
有時候我們會發現,你身處的環境附近有一些小店鋪是沒有在地圖上標記的,也有一些小店鋪就被百度地圖給標記了,這是為什么了?這其實是百度的一個特有的功能,也不是技術活,純粹就是跟申請賬號一樣首先我們打開百度地圖的官網:http://map.baidu.com/
在最下方有個不起眼的文字,商戶免費標注,點進去
按照這個步驟免費申請就得了,這里就不過多贅述
六.地圖高階——繪制覆蓋物
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標等。覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的處理。 覆蓋物包括:本地覆蓋物和搜索覆蓋物 本地覆蓋物的抽象基類:OverlayOptions(核心類) 圓形覆蓋物: CircleOptions 文字覆蓋物: TextOptions marker覆蓋物: MarkerOptions 圓點覆蓋物:DotOptions ground 覆蓋物:GroundOverlayOptions 圓點覆蓋物:DotOptions 多邊形覆蓋物:PolygonOptions 折線覆蓋物:PolylineOptions 弧線覆蓋物:ArcOptions1.繪制圓
既然熟悉了這些基礎的知識,那我們就先來繪制一個圓吧寫一個drawCircle()方法讓onCreate()調用
// 繪制圓 private void drawCircle() {// 1.創建自己CircleOptions circleOptions = new CircleOptions();// 2.設置數據 以世界之窗為圓心,1000米為半徑繪制circleOptions.center(new LatLng(22.5422870000, 113.9804440000))//中心.radius(1000) //半徑.fillColor(0x60FF0000)//填充圓的顏色.stroke(new Stroke(10, 0x600FF000)); //邊框的寬度和顏色//把繪制的圓添加到百度地圖上去mBaiduMap.addOverlay(circleOptions);}說了這么多,還是沒有看圖來的實在,我們來看下截圖
2.繪制文字
同樣的我們在寫一個方法drawText(); // 繪制文字 private void drawText() {TextOptions textOptions = new TextOptions();textOptions.fontColor(Color.RED) //設置字體顏色.text("自定義文字覆蓋物") //設置顯示文本.position(new LatLng(22.5422870000, 113.9804440000)) //設置顯示坐標.fontSize(20) //設置文本大小.typeface(Typeface.SERIF) //設置字體 Android的字體就三種,對稱的,不對稱的,等寬的.rotate(30); //設置旋轉角度//把繪制的圓添加到百度地圖上去mBaiduMap.addOverlay(textOptions);}截圖
3.繪制Mark覆蓋物
Mark覆蓋物就有趣多了,她是可以讓我們自定義一張圖片放上去的,就像那些打車軟件一樣可以讓地圖上看到一些車輛的信息 同樣的,不管三七二十一,我們繼續寫一個方法drawMark(); 先看看我這張要塞進去的圖片 // 繪制mark覆蓋物private void drawMark() {MarkerOptions markerOptions = new MarkerOptions();BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.logo); // 描述圖片markerOptions.position(new LatLng(22.5422870000, 113.9804440000)) // 設置位置.icon(bitmap) // 加載圖片.draggable(true) // 支持拖拽.title("世界之窗旁邊的草房"); // 顯示文本//把繪制的圓添加到百度地圖上去mBaiduMap.addOverlay(markerOptions);}截圖
設置Mark覆蓋物點擊出現泡泡效果
不多說啥,先上個圖給大家看看效果
實現這樣的一個效果,其實就是加了一個pop
我們首先得自己定義一個activity_pop.xml
預覽是這樣子的
首先,我們得初始化一些變量
pop的初始化
//初始化pop private void initPop() {pop = View.inflate(getApplicationContext(), R.layout.activity_pop, null);//必須使用百度的paramsLayoutParams params = new MapViewLayoutParams.Builder().layoutMode(MapViewLayoutParams.ELayoutMode.mapMode) //按照經緯度設置.position(new LatLng(22.5422870000, 113.9804440000)) //這個坐標無所謂的,但是不能傳null.width(MapViewLayoutParams.WRAP_CONTENT) //寬度.height(MapViewLayoutParams.WRAP_CONTENT) //高度.build();mMapView.addView(pop,params);//先設置隱藏,點擊的時候顯示pop.setVisibility(View.INVISIBLE);//初始化這個titletitle = (TextView) pop.findViewById(R.id.title);}mark的點擊事件
/**mark的點擊事件 * 點擊某一個mark在他上放顯示泡泡* 加載pop 添加到mapview 把他設置為隱藏 當點擊的時候更新pop的位置 設置為顯示*/ mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker result) {//處理點擊 ,當點擊的時候更新并且顯示位置LayoutParams params = new MapViewLayoutParams.Builder().layoutMode(MapViewLayoutParams.ELayoutMode.mapMode) //按照經緯度設置位置.position(result.getPosition()) //這個坐標無所謂的,但是不能傳null.width(MapViewLayoutParams.WRAP_CONTENT) //寬度.height(MapViewLayoutParams.WRAP_CONTENT) //高度.yOffset(-5) //相距 正值往下 負值往上.build();mMapView.updateViewLayout(pop, params);pop.setVisibility(View.VISIBLE);//更新下titletitle.setText(result.getTitle());return true;}}); 這邊新加一個功能,就是泡泡輪播切換,咱先看效果圖:
其實實現這個不難,就是在設置icon的時候設置一個icons穿進去一個Bitmap的list
好的,Mark覆蓋物寫得差不多了 ,繼續往下看吧
七.地圖高階——搜索路線標記
真不好意思,最近一直在加班,空閑的時間越來越少,沒事,記錄擼代碼!!! 接下來講的是路線標記,相信不少人應該知道,地圖導航的時候會幫你標記一條路線,我們今天就來實現這個功能,后續有哪些方法有疏漏,也希望博友能指點出來,畢竟我也是技術渣渣 百度地圖移動版API集成搜索服務包括: 位置檢索、周邊檢索、范圍檢索、公交檢索、駕乘檢索、步行檢索 核心類: PoiSearch和OnGetPoiSearchResultListenerRoutePlanSearch和OnGetRoutePlanResultListener 實現思路 初始化PoiSearch類,通過setOnGetPoiSearchResultListener方法注冊搜索結果的監聽對象OnGetPoiSearchResultListener ,實現異步搜索服務。 通過自定義MySearchListener實現類,處理不同的回調方法,獲得搜索結果。 注意, OnGetPoiSearchResultListener只支持一個,以最后一次設置為準 結合覆蓋物展示搜索 本地搜索覆蓋物:PoiOverlay 駕車路線覆蓋物:DrivingRouteOverlay 步行路線覆蓋物:WalkingRouteOverlay 換乘路線覆蓋物:TransitOverlay1.范圍搜索,PoiOverlay的點擊事件(矩形)
我們直接寫一個search()方法讓onCreate()調用吧 直接擼代碼,實現search(); // 范圍搜索private void search() {// 實例化搜索方法PoiSearch newInstance = PoiSearch.newInstance();newInstance.setOnGetPoiSearchResultListener(new SearchListener());// 發出搜索的請求 范圍檢索PoiBoundSearchOption boundOption = new PoiBoundSearchOption();LatLngBounds latLngBounds = new LatLngBounds.Builder() // 確定兩點坐標(東北,西南)// 這里我們隨機弄兩個坐標 分別是深圳世界之窗附近.include(new LatLng(22.5441560000, 113.9828800000)) // 世界之窗右上角的美加廣場.include(new LatLng(22.5413850000, 113.9777770000)) // 世界之窗左下角的一個不知道叫啥的街道.build();boundOption.bound(latLngBounds); // 設置搜索的范圍boundOption.keyword("世界之窗"); // 搜索的關鍵字newInstance.searchInBound(boundOption);} 實現它的Listener class SearchListener implements OnGetPoiSearchResultListener {@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {}@Overridepublic void onGetPoiResult(PoiResult result) {// 收到發送過來的搜索請求之后我們進行處理if(result == null || SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error){Toast.makeText(getApplicationContext(), "未搜索到結果", Toast.LENGTH_LONG).show();return;}//搜索類型的類PoiOverlay overlay = PoiOverlay(mBaiduMap); //處理搜索Poi的覆蓋物mBaiduMap.setOnMarkerClickListener(overlay);// 把事件分發給overlay,overlay才能處理點擊事件overlay.setData(result); //設置結果overlay.addToMap;//把搜索的結果添加到地圖中去overlay.zoomToSpan(); //自動縮放到所以的mark覆蓋物都能看到}} 自己實現它的點擊事件 //自己實現點擊事件class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap arg0) {super(arg0);}@Overridepublic boolean onPoiClick(int index) {PoiResult poiResult = getPoiResult();PoiInfo poiInfo = poiResult.getAllPoi().get(index);// 得到點擊的那個poi信息String text = poiInfo.name + "," + poiInfo.address;Toast.makeText(getApplicationContext(), text, 0).show();return super.onPoiClick(index);}} 官方的效果,點擊后Toast2.周邊搜索(圓形)
周邊搜索和范圍搜索基本一致,我就直接上代碼了 private void search() {poiSearch = PoiSearch.newInstance();poiSearch.setOnGetPoiSearchResultListener(new MyListener());PoiNearbySearchOption nearbyOption = new PoiNearbySearchOption();nearbyOption.location(hmPos);// 設置中心點nearbyOption.radius(1000);// 設置半徑 單位是米nearbyOption.keyword("加油站");// 關鍵字poiSearch.searchNearby(nearbyOption);}class MyListener implements OnGetPoiSearchResultListener{@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {if(result==null||SearchResult.ERRORNO.RESULT_NOT_FOUND==result.error){Toast.makeText(getApplicationContext(), "未搜索到結果", 0).show();return;}String text = result.getAddress()+ "::" + result.getCommentNum() + result.getEnvironmentRating();Toast.makeText(getApplicationContext(), text, 0).show();}@Overridepublic void onGetPoiResult(PoiResult result) {if(result==null||SearchResult.ERRORNO.RESULT_NOT_FOUND==result.error){Toast.makeText(getApplicationContext(), "未搜索到結果", 0).show();return;}PoiOverlay overlay = new MyPoiOverlay(baiduMap);// 搜索poi的覆蓋物baiduMap.setOnMarkerClickListener(overlay);// 把事件分發給overlay,overlay才能處理點擊事件overlay.setData(result);// 設置結果overlay.addToMap();// 把搜索的結果添加到地圖中overlay.zoomToSpan();// 縮放地圖,使所有Overlay都在合適的視野內 注: 該方法只對Marker類型的overlay有效}}class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap arg0) {super(arg0);}@Overridepublic boolean onPoiClick(int index) {PoiResult poiResult = getPoiResult();PoiInfo poiInfo = poiResult.getAllPoi().get(index);// 得到點擊的那個poi信息String text = poiInfo.name + "," + poiInfo.address;Toast.makeText(getApplicationContext(), text, 0).show();PoiDetailSearchOption detailOption = new PoiDetailSearchOption();detailOption.poiUid(poiInfo.uid);// 設置poi的uidpoiSearch.searchPoiDetail(detailOption);return super.onPoiClick(index);}}3.城市內搜索
基本上是一摸一樣的 private PoiSearch poiSearch; private int currentPageIndex = 0; private void search() {poiSearch = PoiSearch.newInstance();poiSearch.setOnGetPoiSearchResultListener(new MyListener());search();PoiCitySearchOption cityOption = new PoiCitySearchOption();cityOption.city("北京");cityOption.keyword("加油站");cityOption.pageNum(currentPageIndex);poiSearch.searchInCity(cityOption);}class MyListener implements OnGetPoiSearchResultListener {@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {}@Overridepublic void onGetPoiResult(PoiResult result) {if (result == null|| SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) {Toast.makeText(getApplicationContext(), "未搜索到結果", 0).show();return;}String text = "共" + result.getTotalPageNum() + "頁,共"+ result.getTotalPoiNum() + "條,當前第"+ result.getCurrentPageNum() + "頁,當前頁"+ result.getCurrentPageCapacity() + "條";Toast.makeText(getApplicationContext(), text, 1).show();baiduMap.clear();// 清空地圖所有的 Overlay 覆蓋物以及 InfoWindowPoiOverlay overlay = new MyPoiOverlay(baiduMap);// 搜索poi的覆蓋物baiduMap.setOnMarkerClickListener(overlay);// 把事件分發給overlay,overlay才能處理點擊事件overlay.setData(result);// 設置結果overlay.addToMap();// 把搜索的結果添加到地圖中overlay.zoomToSpan();// 縮放地圖,使所有Overlay都在合適的視野內 注:// 該方法只對Marker類型的overlay有效}}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if(keyCode==KeyEvent.KEYCODE_1){currentPageIndex++;search();}return super.onKeyDown(keyCode, event);}class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap arg0) {super(arg0);}@Overridepublic boolean onPoiClick(int index) {PoiResult poiResult = getPoiResult();PoiInfo poiInfo = poiResult.getAllPoi().get(index);// 得到點擊的那個poi信息String text = poiInfo.name + "," + poiInfo.address;Toast.makeText(getApplicationContext(), text, 0).show();return super.onPoiClick(index);}}4.路線檢索(駕車路線)
//駕車路線private void driving(){RoutePlanSearch newInstance = RoutePlanSearch.newInstance();newInstance.setOnGetRoutePlanResultListener(new MyListener());//駕車路線DrivingRoutePlanOption drivingOption = new DrivingRoutePlanOption();PlanNode from = PlanNode.withLocation(new LatLng(22.5422870000, 113.9804440000)); //設置起點世界之窗PlanNode to = PlanNode.withLocation(new LatLng(22.5455910000,113.9880900000)); //設置終點就附近的歡樂谷drivingOption.from(from);drivingOption.to(to);drivingOption.policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_DIS_FIRST); //方案:最短距離 這個自己設置 比如時間短之類的newInstance.drivingSearch(drivingOption);}class MyListener implements OnGetRoutePlanResultListener{@Overridepublic void onGetDrivingRouteResult(DrivingRouteResult result) {//駕車if(result == null || SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error){Toast.makeText(getApplicationContext(), "未搜索到結果", Toast.LENGTH_LONG).show();return;}//開始處理結果了DrivingRouteOverlay overlay = new MyDrivingOverlay(baiduMap);baiduMap.setOnMarkerClickListener(overlay);// 把事件傳遞給overlayoverlay.setData(result.getRouteLines().get(0));// 設置線路為第一條overlay.addToMap();overlay.zoomToSpan();}@Overridepublic void onGetTransitRouteResult(TransitRouteResult result) {// 公交換乘}@Overridepublic void onGetWalkingRouteResult(WalkingRouteResult result) {// 步行}}class MyDrivingOverlay extends DrivingRouteOverlay{public MyDrivingOverlay(BaiduMap arg0) {super(arg0);}@Overridepublic BitmapDescriptor getStartMarker() {//覆寫此方法以改變默認起點圖標return BitmapDescriptorFactory.fromResource(R.drawable.icon_st);}@Overridepublic BitmapDescriptor getTerminalMarker() {//覆寫此方法以改變默認終點圖標return BitmapDescriptorFactory.fromResource(R.drawable.icon_en);}} 官方的效果圖5.6.公交換乘和步行路線,其實和駕車路線的寫法是一樣的這里就不寫了
寫的時候不知道為什么我的Overlay類來是創建不出來,所以代碼拙劣的地方還請海涵八.地圖高階——定位系統
這個相信是大家經常用到的 LocationClient和BDLocationListener 首先需要打開定位圖層BaiduMap.setMyLocationEnabled(true); 設置監聽器LocationClient. registerLocationListener(BDLocationListener) 設置定位模式baiduMap. setLocationMode(LocationMode) Hight_Accuracy,高精度定位模式:這種定位模式下,會同時使用網絡定位和GPS定位,優先返回最高精度的定位結果; Battery_Saving,低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網絡定位(Wi-Fi和基站定位) Device_Sensors,僅用設備定位模式:這種定位模式下,不需要連接網絡,只使用GPS進行定位,這種模式下不支持室內環境的定位 設置定位顯示模式BaiduMap.setMyLocationConfigeration(MyLocationConfiguration) 定位數據獲取:在BDLocationListener. onReceiveLocation(BDLocation result)方法中設置定位數據, baiduMap.setMyLocationData(MyLocationData); 一個GPS定位,不過必須要三顆星以上才可定位,不然是定不了的,還有一個基站地位,他其實每個基站都有一個ID,就是一個位置,查到最近基站的位置然后去服務器里請求返回位置信息,還有一個wifi定位,當你的手機連接wifi,你開始定位的時候,把wifi的地址發送到百度的服務器,服務器會把大部分wifi地址都有收錄,直接返回經緯度地址:http://developer.baidu.com/map/index.php?title=android-locsdk/guide/v5-0
我們根據百度提供的文檔去做1.在application標簽中聲明service組件,每個app擁有自己單獨的定位service
<service android:name="com.baidu.location.f" android:enabled="true" //跑在一個新的進程中 android:process=":remote"> </service> 主要用到的兩個類 public LocationClient mLocationClient; public BDLocationListener myListener; private BitmapDescriptor geo; 然后我們直接寫個方法lacate(); private void lacate() {mLocationClient = new LocationClient(getApplicationContext());myListener = new MyListener();mLocationClient.registerLocationListener(myListener);LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationMode.Hight_Accuracy);// 設置定位模式option.setCoorType("bd09ll");// 返回的定位結果是百度經緯度,默認值gcj02option.setScanSpan(5000);// 設置發起定位請求的間隔時間為5000msoption.setIsNeedAddress(true);// 返回的定位結果包含地址信息option.setNeedDeviceDirect(true);// 返回的定位結果包含手機機頭的方向mLocationClient.setLocOption(option);geo = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, geo);baiduMap.setMyLocationConfigeration(configuration);// 設置定位顯示的模式baiduMap.setMyLocationEnabled(true);// 打開定位圖層} 繼續自己寫個Listener class MyListener implements BDLocationListener {@Overridepublic void onReceiveLocation(BDLocation result) {if (result != null) {MyLocationData data = new MyLocationData.Builder().latitude(result.getLatitude()).longitude(result.getLongitude()).build();baiduMap.setMyLocationData(data);}}} 我們可以模擬一下使用各種方式去定位 @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1:// 正常baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, geo));// 設置定位顯示的模式break;case KeyEvent.KEYCODE_2:// 羅盤baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.COMPASS, true, geo));// 設置定位顯示的模式break;case KeyEvent.KEYCODE_3:// 跟隨baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, geo));// 設置定位顯示的模式break;default:break;}return super.onKeyDown(keyCode, event);}百度地圖算是寫完一半了,為什么說只寫完了一半,因為時間緊迫,里面肯定會有些錯誤的編寫,不過思想是對的,你按照步驟來,結合你對百度API的認知,這些其實都是很簡單就去實現的,這里只是作為一個拋磚引玉
后續還會持續修訂更改,如有錯誤,歡迎點評,謝謝了!
Demo下載地址:http://download.csdn.net/detail/qq_26787115/9379582
總結
以上是生活随笔為你收集整理的Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中兴华为继续应诉欧盟无线网卡反倾销
- 下一篇: 美团和滴滴,跨领域的竞争