百度地圖 SDK升級了,因此就試試這個新版的,發現和之前的又不少不同的地方,可是熟悉之前的版本改動挺大的,想設置個MapView的各類參數都不知道怎麼搞,摸索了好久纔有點眉目-_-!java
尤爲是百度的API文檔,簡直讓人抓狂...android
實現功能:使用自定義的Fragment做爲百度地圖,能夠自動定位,手動定位,定位標誌等等..git
還能夠實現更多的功能...api
首先下載好百度地圖的最新SDK 定位SDKv4.2 , 地圖SDKv3.0.0app
按照官方說明,下載好sdk,導入工程ide
須要先到百度控制檯申請ak,而後再 manifest中添加各類權限和ak配置,Service佈局
直接上代碼了動畫
javaui
1 /** 2 * 3 */ 4 package cn.edu.hstc.xszn.ui; 5 6 import android.annotation.SuppressLint; 7 import android.content.Context; 8 import android.os.Bundle; 9 import android.support.v4.app.Fragment; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.view.ViewGroup; 14 import android.widget.ImageButton; 15 import android.widget.TextView; 16 import android.widget.Toast; 17 import cn.edu.hstc.xszn.R; 18 import cn.edu.hstc.xszn.common.L; 19 20 import com.baidu.location.BDLocation; 21 import com.baidu.location.BDLocationListener; 22 import com.baidu.location.LocationClient; 23 import com.baidu.location.LocationClientOption; 24 import com.baidu.location.LocationClientOption.LocationMode; 25 import com.baidu.mapapi.SDKInitializer; 26 import com.baidu.mapapi.map.BaiduMap; 27 import com.baidu.mapapi.map.BaiduMap.OnMyLocationClickListener; 28 import com.baidu.mapapi.map.InfoWindow; 29 import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener; 30 import com.baidu.mapapi.map.MapStatus; 31 import com.baidu.mapapi.map.MapStatusUpdate; 32 import com.baidu.mapapi.map.MapStatusUpdateFactory; 33 import com.baidu.mapapi.map.MapView; 34 import com.baidu.mapapi.map.MyLocationConfigeration; 35 import com.baidu.mapapi.map.MyLocationData; 36 import com.baidu.mapapi.model.LatLng; 37 38 /** 39 * @Description 40 * @author act262 41 * @version 1.0 42 * @since 2014-6-27 上午10:49:39 43 * 44 */ 45 @SuppressLint("ValidFragment") 46 public class FragmentCampusBaiduMap extends Fragment { 47 48 /** 定位按鈕 */ 49 private ImageButton locateButton; 50 /** 地圖View */ 51 private MapView mapView = null; 52 /** 百度地圖的實體 */ 53 private BaiduMap baiduMap = null; 54 /** 百度定位核心 */ 55 private LocationClient locationClient = null; 56 /** 位置變化監聽 */ 57 private LocationListener listener; 58 /** 當前定位的數據 */ 59 private MyLocationData locationData; 60 /** 彈出窗覆蓋物 */ 61 private InfoWindow infoWindow; 62 /** 顯示當前位置的信息小窗口 */ 63 private View tipView; 64 /** 顯示在小窗口上的文字 */ 65 private TextView tipTextView; 66 67 /** 首次定位 */ 68 private boolean isFirstLocate = true; 69 70 private final String TAG = this.getClass().getSimpleName(); 71 72 public static FragmentCampusBaiduMap getInstance(Context context) { 73 return new FragmentCampusBaiduMap(context); 74 } 75 76 public FragmentCampusBaiduMap(Context context) { 77 // 使用百度map時必須的初始化工做 78 SDKInitializer.initialize(context); 79 } 80 81 @Override 82 public void onCreate(Bundle arg0) { 83 super.onCreate(arg0); 84 L.d(TAG, "onCreate"); 85 } 86 87 @Override 88 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle arg2) { 89 L.d(TAG, "onCreateView"); 90 View rootView = inflater.inflate(R.layout.fragment_campus_baidumap, null); 91 mapView = (MapView) rootView.findViewById(R.id.mapView_fragment_campus_baidumap); 92 locateButton = (ImageButton) rootView.findViewById(R.id.ib_fragment_campus_baidumap_locate); 93 locateButton.setOnClickListener(new OnClickListener() { 94 public void onClick(View v) { 95 requestLocate(); // 手動請求定位 96 } 97 }); 98 99 // 初始化小窗口 100 tipView = inflater.inflate(R.layout.view_fragment_campus_baidumap_location_tip, null); 101 tipTextView = (TextView) tipView.findViewById(R.id.tv_view_fragment_campus_baidumap_location_tip); 102 return rootView; 103 } 104 105 // 手動請求定位 106 private void requestLocate() { 107 Toast.makeText(getActivity(), "正在定位...", Toast.LENGTH_SHORT).show(); 108 if (locationClient != null && locationClient.isStarted()) { 109 locationClient.requestLocation(); 110 } else { 111 Toast.makeText(getActivity(), "定位失敗", Toast.LENGTH_SHORT).show(); 112 } 113 } 114 115 boolean isShowInfoWindow = false; 116 117 private void initMap() { 118 baiduMap = mapView.getMap(); 119 baiduMap.setOnMyLocationClickListener(new OnMyLocationClickListener() { 120 121 @Override 122 public boolean onMyLocationClick() { 123 if (isShowInfoWindow) { 124 isShowInfoWindow = false; 125 baiduMap.hideInfoWindow(); 126 } else { 127 isShowInfoWindow = true; 128 baiduMap.showInfoWindow(infoWindow); 129 } 130 return false; 131 } 132 }); 133 134 // 開啓定位圖層 135 baiduMap.setMyLocationEnabled(true); 136 // 設置百度地圖的一些狀態,放大等級, 137 baiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder(baiduMap.getMapStatus()).zoom(16).build())); // 設置放大等級爲16 138 // 配置定位圖層顯示方式,必定要開啓了定位圖層後再設置 139 baiduMap.setMyLocationConfigeration(new MyLocationConfigeration(MyLocationConfigeration.LocationMode.FOLLOWING, true, null)); // 設置爲跟隨模式,顯示手機方向的箭頭 140 141 locationClient = new LocationClient(getActivity().getApplicationContext()); 142 listener = new LocationListener(); 143 locationClient.registerLocationListener(listener); // 註冊位置監聽器 144 145 // 定位參數控制 146 LocationClientOption option = new LocationClientOption(); 147 option.setLocationMode(LocationMode.Hight_Accuracy);// 設置定位模式 148 option.setOpenGps(true); // 打開GPS 149 option.setTimeOut(10 * 1000); // 超時 150 option.setCoorType("bd09ll");// 返回的定位結果是百度經緯度,默認值gcj02 151 option.setScanSpan(60 * 1000);// 設置發起定位請求的間隔時間爲5000ms,將自動發起請求 152 option.setIsNeedAddress(true);// 返回的定位結果包含地址信息 153 option.setNeedDeviceDirect(true);// 返回的定位結果包含手機機頭的方向 154 locationClient.setLocOption(option); 155 156 } 157 158 @Override 159 public void onStart() { 160 super.onStart(); 161 initMap(); 162 locationClient.start(); // 啓動定位,發起第一次自動請求 163 } 164 165 @Override 166 public void onResume() { 167 // MapView的生命週期與Activity同步,當activity恢復時需調用MapView.onResume() 168 mapView.onResume(); 169 super.onResume(); 170 } 171 172 @Override 173 public void onPause() { 174 mapView.onPause(); 175 super.onPause(); 176 } 177 178 @Override 179 public void onDestroy() { 180 if (locationClient != null) { 181 locationClient.stop(); // 退出中止定位 182 } 183 baiduMap.setMyLocationEnabled(false); // 關閉定位圖層 184 mapView.onDestroy(); 185 mapView = null; 186 super.onDestroy(); 187 } 188 189 private class LocationListener implements BDLocationListener { 190 191 private void initInfoWindow(LatLng point) { 192 OnInfoWindowClickListener infoWindowClickListener = new OnInfoWindowClickListener() { 193 @Override 194 public void onInfoWindowClick() { 195 baiduMap.hideInfoWindow(); 196 isShowInfoWindow = false; 197 } 198 }; 199 infoWindow = new InfoWindow(tipView, point, infoWindowClickListener); 200 } 201 202 @Override 203 public void onReceiveLocation(BDLocation location) { 204 L.d(TAG, "onReceiveLocation"); 205 if (location == null) { 206 return; 207 } 208 StringBuffer sb = new StringBuffer(256); 209 sb.append("time : "); 210 sb.append(location.getTime()); 211 sb.append("\nerror code : "); 212 sb.append(location.getLocType()); // 定位方式 213 sb.append("\nlatitude : "); 214 sb.append(location.getLatitude()); // 緯度 215 sb.append("\nlontitude : "); 216 sb.append(location.getLongitude()); // 經度 217 sb.append("\nradius : "); 218 sb.append(location.getRadius()); // 定位精度 219 sb.append("\ndirection : "); 220 sb.append(location.getDirection()); // 手機當前方向 221 sb.append("\naltitude : "); 222 sb.append(location.getAltitude()); // 高度 223 sb.append("\bspeed : "); 224 sb.append(location.getSpeed()); // 速度 225 sb.append("\noperators : "); 226 sb.append(location.getOperators()); 227 if (location.getLocType() == BDLocation.TypeGpsLocation) { 228 sb.append("\nspeed : "); 229 sb.append(location.getSpeed()); 230 sb.append("\nsatellite : "); 231 sb.append(location.getSatelliteNumber()); // 衛星數 232 } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { 233 sb.append("\naddr : "); 234 sb.append(location.getAddrStr()); // 詳細地址信息 235 sb.append("\nprovince:"); 236 sb.append(location.getProvince()); // 省 237 sb.append("\ncity:"); 238 sb.append(location.getCity()); // 城市 239 sb.append("\ndistrict:"); 240 sb.append(location.getDistrict()); // 區縣 241 } 242 L.d(TAG, sb.toString()); 243 244 locationData = new MyLocationData.Builder().accuracy(location.getRadius()) // 定位的精確度 245 .direction(location.getDirection()) // 定位的方向 0~360度 246 .latitude(location.getLatitude()).longitude(location.getLongitude()) // 經緯度 247 .speed(location.getSpeed()).build(); 248 249 // 設置定位數據到定位圖層上,就是顯示當前位置的那個點和圓圈 250 baiduMap.setMyLocationData(locationData); 251 252 LatLng point = new LatLng(location.getLatitude(), location.getLongitude()); 253 // 個人地理位置 254 String myPosition = "個人位置\n" + location.getAddrStr(); 255 256 // 第一次進入百度地圖 257 if (isFirstLocate) { 258 isFirstLocate = false; 259 // 移動到個人位置 260 // baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(point), 261 // 600); // 默認動畫效果時間300ms 262 } 263 264 // 基於原來的status上改變指定的參數 265 MapStatus mapStatus = new MapStatus.Builder(baiduMap.getMapStatus()).target(point).build(); 266 MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus); 267 baiduMap.animateMapStatus(mapStatusUpdate); // 改變,這裏設置成隨着移動而改變位置 268 269 // 顯示小窗口信息 270 if (location.getAddrStr().length() > 0) { 271 initInfoWindow(point); 272 273 tipTextView.setText("" + myPosition); 274 isShowInfoWindow = true; 275 // 設置顯示個人位置 276 baiduMap.showInfoWindow(infoWindow); // 顯示 277 } 278 } 279 } 280 281 }
Fragment的佈局.xmlthis
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <!-- 百度地圖的 MapView --> 7 8 <com.baidu.mapapi.map.MapView 9 android:id="@+id/mapView_fragment_campus_baidumap" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:clickable="true" /> 13 14 <!-- 手動定位按鈕 --> 15 16 <ImageButton 17 android:id="@+id/ib_fragment_campus_baidumap_locate" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:layout_alignParentRight="true" 21 android:layout_alignParentTop="true" 22 android:layout_marginRight="25dp" 23 android:layout_marginTop="10dp" 24 android:background="@drawable/ic_baidumap_locate" /> 25 26 </RelativeLayout>
tip彈窗佈局.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 個人位置提示 --> 3 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 android:layout_width="wrap_content" 5 android:layout_height="wrap_content" > 6 7 <TextView 8 android:id="@+id/tv_view_fragment_campus_baidumap_location_tip" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:background="@drawable/bg_location_tips" 12 android:gravity="center" 13 android:textColor="@android:color/white" 14 android:textSize="16sp" /> 15 16 </FrameLayout>
在MainActivity中使用這個Fragment就行了
運行效果圖