Android计步器悦步——百度地图
(源代碼見 https://github.com/14353350/Yuebu-Pedometer)
申請(qǐng)密鑰
- 每個(gè)Key唯一對(duì)應(yīng)一個(gè)APP,如果您的APP修改了包名或者發(fā)布的時(shí)候打包的簽名文件改變了,則改變前后的APP被視為兩個(gè)APP。因此,多個(gè)APP【包括一份代碼多個(gè)包名打包】需申請(qǐng)多個(gè)與之對(duì)應(yīng)的Key
 - 在同一個(gè)工程中同時(shí)使用百度地圖SDK、定位SDK、導(dǎo)航SDK 和全景SDK的全部或者任何組合,可以共用同一個(gè)key 
SHA1簡單獲取方法:如圖點(diǎn)擊signingReport即可查看
 
配置環(huán)境
- 在相關(guān)下載里下載SDK,推薦自定義下載。
 - 在工程app/libs目錄下放入baidumapapi_vX_X_X.jar包,在src/main/目錄下新建jniLibs目錄,將armeabi等拷入 
 - 
在AndroidManifest中添加開發(fā)密鑰、所需權(quán)限等信息
- 在application中添加開發(fā)密鑰
 
<application> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="開發(fā)者 key" /> </application>- 添加所需權(quán)限
 
<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" /> 
顯示地圖
- 
在布局xml文件中添加地圖控件
<com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> - 
在應(yīng)用程序創(chuàng)建時(shí)初始化 SDK引用的Context 全局變量
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//在使用SDK各組件之前初始化context信息,傳入ApplicationContext//注意該方法要再setContentView方法之前實(shí)現(xiàn)SDKInitializer.initialize(getApplicationContext());setContentView(R.layout.activity_navigate);...mMapView = (MapView) findViewById(R.id.baidumapView);//普通地圖mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);... - 
管理地圖生命周期
@Override protected void onDestroy() {super.onDestroy();//在activity執(zhí)行onDestroy時(shí)執(zhí)行mMapView.onDestroy(),實(shí)現(xiàn)地圖生命周期管理mMapView.onDestroy(); } @Override protected void onResume() {super.onResume();//在activity執(zhí)行onResume時(shí)執(zhí)行mMapView. onResume (),實(shí)現(xiàn)地圖生命周期管理mMapView.onResume(); } @Override protected void onPause() {super.onPause();//在activity執(zhí)行onPause時(shí)執(zhí)行mMapView. onPause (),實(shí)現(xiàn)地圖生命周期管理mMapView.onPause(); } 
定位
- 
在Application標(biāo)簽中聲明SERVICE組件
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service> - 
聲明使用權(quán)限
<!-- 這個(gè)權(quán)限用于進(jìn)行網(wǎng)絡(luò)定位--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!-- 這個(gè)權(quán)限用于訪問GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <!-- 用于訪問wifi網(wǎng)絡(luò)信息,wifi信息會(huì)用于進(jìn)行網(wǎng)絡(luò)定位--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <!-- 獲取運(yùn)營商信息,用于支持提供運(yùn)營商信息相關(guān)的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <!-- 這個(gè)權(quán)限用于獲取wifi的獲取權(quán)限,wifi信息會(huì)用來進(jìn)行網(wǎng)絡(luò)定位--> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <!-- 用于讀取手機(jī)當(dāng)前的狀態(tài)--> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <!-- 寫入擴(kuò)展存儲(chǔ),向擴(kuò)展卡寫入數(shù)據(jù),用于寫入離線定位數(shù)據(jù)--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!-- 訪問網(wǎng)絡(luò),網(wǎng)絡(luò)定位需要上網(wǎng)--> <uses-permission android:name="android.permission.INTERNET" /> <!-- SD卡讀取權(quán)限,用戶寫入離線定位數(shù)據(jù)--> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> - 
初始化LocationClient類
Context需要時(shí)全進(jìn)程有效的Context,推薦用getApplicationConext獲取全進(jìn)程有效的Context。public LocationClient mLocationClient = null; public BDLocationListener myListener = new MyLocationListener(); ... @Override protected void onCreate(Bundle savedInstanceState) {...//設(shè)置定位及其圖標(biāo)Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.pointer),100,100,true);BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap);MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL,true,bitmapDescriptor);mBaiduMap.setMyLocationEnabled(true);mBaiduMap.setMyLocationConfigeration(config);//定位按鈕mToggleButton = (ToggleButton) findViewById(R.id.button_center);mLocationClient = new LocationClient(getApplicationContext()); //聲明LocationClient類mLocationClient.registerLocationListener( myListener ); //注冊(cè)監(jiān)聽函數(shù)initLocation();//開始定位mLocationClient.start(); - 
配置定位SDK參數(shù)
設(shè)置定位參數(shù)包括:定位模式(高精度定位模式、低功耗定位模式和僅用設(shè)備定位模式),返回坐標(biāo)類型,是否打開GPS,是否返回地址信息、位置語義化信息、POI信息等等。private void initLocation(){LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可選,默認(rèn)高精度,設(shè)置定位模式,高精度,低功耗,僅設(shè)備option.setCoorType("bd09ll");//可選,默認(rèn)gcj02,設(shè)置返回的定位結(jié)果坐標(biāo)系int span=1000;option.setScanSpan(span);//可選,默認(rèn)0,即僅定位一次,設(shè)置發(fā)起定位請(qǐng)求的間隔需要大于等于1000ms才是有效的option.setIsNeedAddress(true);//可選,設(shè)置是否需要地址信息,默認(rèn)不需要option.setOpenGps(true);//可選,默認(rèn)false,設(shè)置是否使用gpsoption.setLocationNotify(true);//可選,默認(rèn)false,設(shè)置是否當(dāng)GPS有效時(shí)按照1S/1次頻率輸出GPS結(jié)果option.setIsNeedLocationDescribe(true);//可選,默認(rèn)false,設(shè)置是否需要位置語義化結(jié)果,可以在BDLocation.getLocationDescribe里得到,結(jié)果類似于“在北京天安門附近”option.setIsNeedLocationPoiList(false);//可選,默認(rèn)false,設(shè)置是否需要POI結(jié)果,可以在BDLocation.getPoiList里得到option.setIgnoreKillProcess(true);//可選,默認(rèn)true,定位SDK內(nèi)部是一個(gè)SERVICE,并放到了獨(dú)立進(jìn)程,設(shè)置是否在stop的時(shí)候殺死這個(gè)進(jìn)程,默認(rèn)不殺死option.SetIgnoreCacheException(false);//可選,默認(rèn)false,設(shè)置是否收集CRASH信息,默認(rèn)收集option.setEnableSimulateGps(false);//可選,默認(rèn)false,設(shè)置是否需要過濾GPS仿真結(jié)果,默認(rèn)需要mLocationClient.setLocOption(option); } - 
實(shí)現(xiàn)BDLocationListener接口
BDLocationListener為結(jié)果監(jiān)聽接口,異步獲取定位結(jié)果public class MyLocationListener implements BDLocationListener {@Overridepublic void onReceiveLocation(BDLocation location) {//Receive LocationStringBuffer sb = new StringBuffer(256);...//顯示新位置if(mToggleButton.isChecked()){makeUseOfNewLocation();}sb.append("time : ");sb.append(location.getTime());sb.append("\nerror code : ");sb.append(location.getLocType());sb.append("\nlatitude : ");sb.append(location.getLatitude());sb.append("\nlontitude : ");sb.append(location.getLongitude());sb.append("\nradius : ");sb.append(location.getRadius());if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結(jié)果sb.append("\nspeed : ");sb.append(location.getSpeed());// 單位:公里每小時(shí)sb.append("\nsatellite : ");sb.append(location.getSatelliteNumber());sb.append("\nheight : ");sb.append(location.getAltitude());// 單位:米sb.append("\ndirection : ");sb.append(location.getDirection());// 單位度sb.append("\naddr : ");sb.append(location.getAddrStr());sb.append("\ndescribe : ");sb.append("gps定位成功");} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 網(wǎng)絡(luò)定位結(jié)果sb.append("\naddr : ");sb.append(location.getAddrStr());//運(yùn)營商信息sb.append("\noperationers : ");sb.append(location.getOperators());sb.append("\ndescribe : ");sb.append("網(wǎng)絡(luò)定位成功");} else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 離線定位結(jié)果sb.append("\ndescribe : ");sb.append("離線定位成功,離線定位結(jié)果也是有效的");} else if (location.getLocType() == BDLocation.TypeServerError) {sb.append("\ndescribe : ");sb.append("服務(wù)端網(wǎng)絡(luò)定位失敗,可以反饋IMEI號(hào)和大體定位時(shí)間到loc-bugs@baidu.com,會(huì)有人追查原因");} else if (location.getLocType() == BDLocation.TypeNetWorkException) {sb.append("\ndescribe : ");sb.append("網(wǎng)絡(luò)不同導(dǎo)致定位失敗,請(qǐng)檢查網(wǎng)絡(luò)是否通暢");} else if (location.getLocType() == BDLocation.TypeCriteriaException) {sb.append("\ndescribe : ");sb.append("無法獲取有效定位依據(jù)導(dǎo)致定位失敗,一般是由于手機(jī)的原因,處于飛行模式下一般會(huì)造成這種結(jié)果,可以試著重啟手機(jī)");}sb.append("\nlocationdescribe : ");sb.append(location.getLocationDescribe());// 位置語義化信息List<Poi> list = location.getPoiList();// POI數(shù)據(jù)if (list != null) {sb.append("\npoilist size = : ");sb.append(list.size());for (Poi p : list) {sb.append("\npoi= : ");sb.append(p.getId() + " " + p.getName() + " " + p.getRank());}}Log.i("BaiduLocationApiDem", sb.toString());} } - 
當(dāng)ToggleButton選中地圖自動(dòng)顯示當(dāng)前位置
private void makeUseOfNewLocation(){MyLocationData.Builder builder = new MyLocationData.Builder().direction(mCurrentRotation).latitude(MyLatLng.latitude).longitude(MyLatLng.longitude);mBaiduMap.setMyLocationData(builder.build());//MapStatus使居中MapStatus mapStatus = new MapStatus.Builder().target(MyLatLng).build();MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);mBaiduMap.setMapStatus(mapStatusUpdate); } - 
當(dāng)滑動(dòng)地圖時(shí)設(shè)置Toggle Button不選中
mMapView.getMap().setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {@Overridepublic void onTouch(MotionEvent motionEvent) {switch (motionEvent.getAction()){case MotionEvent.ACTION_MOVE:mToggleButton.setChecked(false);break;default:break;}}}); 
利用磁、加速度傳感器顯示朝向
- 
獲取傳感器管理器,注冊(cè)\注銷磁、加速度傳感器
@Override protected void onCreate(Bundle savedInstanceState) {...//磁、加速度傳感器msensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);mMagneticSensor = msensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);mAccelerometerSensor = msensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);... } @Override protected void onResume() {super.onResume();...msensorManager.registerListener(mSensorEventListener, mMagneticSensor, SensorManager.SENSOR_DELAY_GAME);msensorManager.registerListener(mSensorEventListener,mAccelerometerSensor,SensorManager.SENSOR_DELAY_GAME); } @Override protected void onPause() {super.onPause();...msensorManager.unregisterListener(mSensorEventListener); } - 
處理傳感器數(shù)據(jù)
private SensorEventListener mSensorEventListener = new SensorEventListener() {float[] accValues = null;float[] magValues = null;@Overridepublic void onSensorChanged(SensorEvent event) {switch (event.sensor.getType()) {case Sensor.TYPE_ACCELEROMETER:// do something about values of accelerometeraccValues = event.values.clone();break;case Sensor.TYPE_MAGNETIC_FIELD:// do something about values of magnetic fieldmagValues = event.values.clone();break;default:break;}float[] R = new float[9];float[] values = new float[3];if(accValues != null && magValues != null){//計(jì)算朝向SensorManager.getRotationMatrix(R, null, accValues, magValues);SensorManager.getOrientation(R, values);mCurrentRotation = (float) Math.round(Math.toDegrees(values[0])*100)/100;//更新if(MyLatLng!=null){MyLocationData.Builder builder = new MyLocationData.Builder().direction(mCurrentRotation).latitude(MyLatLng.latitude).longitude(MyLatLng.longitude);mBaiduMap.setMyLocationData(builder.build());}}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {} }; 
POI檢索
- 
創(chuàng)建POI檢索實(shí)例,POI檢索監(jiān)聽者(這里只在地圖上顯示前10個(gè)搜索結(jié)果)
private void POISearch(){//創(chuàng)建POI檢索實(shí)例mPoiSearch = PoiSearch.newInstance();//POI檢索監(jiān)聽者OnGetPoiSearchResultListener poiListener = new OnGetPoiSearchResultListener(){public void onGetPoiResult(PoiResult result){List<PoiInfo> list = result.getAllPoi();if(list == null){Toast.makeText(getApplicationContext(),"你搜索的結(jié)果為空",Toast.LENGTH_SHORT).show();return;}//獲取POI檢索結(jié)果mBaiduMap.clear();//列表大小為1頁容量即10for(int i=0;i<list.size();i++){LatLng point = list.get(i).location;//這里有從A-J共10個(gè)marker圖標(biāo),通過圖片名獲取String icon_name="icon_mark"+(char)(97+i);//構(gòu)建Marker圖標(biāo)BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(getDrawableResource(icon_name));//額外信息打包,包括地址和電話Bundle bundle = new Bundle();bundle.putString("address",list.get(i).address);bundle.putString("phoneNum",list.get(i).phoneNum);//構(gòu)建MarkerOption,用于在地圖上添加MarkerOverlayOptions option = new MarkerOptions().position(point).icon(bitmap).title(list.get(i).name).extraInfo(bundle);//在地圖上添加Marker,并顯示mBaiduMap.addOverlay(option);}//取消自動(dòng)顯示當(dāng)前位置mToggleButton.setChecked(false);//地圖顯示A所在位置MapStatus mapStatus = new MapStatus.Builder().target(list.get(0).location).build();MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);mBaiduMap.setMapStatus(mapStatusUpdate);}public void onGetPoiDetailResult(PoiDetailResult result){//獲取Place詳情頁檢索結(jié)果}public void onGetPoiIndoorResult(PoiIndoorResult result){};};mPoiSearch.setOnGetPoiSearchResultListener(poiListener);if(!TextUtils.isEmpty(search_keywords.getText())){//PoiNearbySearchOption,檢索方圓xx米內(nèi),默認(rèn)每頁10條mPoiSearch.searchNearby((new PoiNearbySearchOption().location(MyLatLng).radius(10000).keyword(search_keywords.getText().toString()).pageNum(10)));} } - 
通過圖片名獲取圖片資源(drawable路徑下,若在mipmap路徑類似),使用的是反射機(jī)制,有興趣的可以了解一下。
public int getDrawableResource(String imageName){Log.v("MyDebug",imageName);Class drawable = R.drawable.class;try {Field field = drawable.getField(imageName);int resId = field.getInt(imageName);return resId;} catch (NoSuchFieldException e) {//如果沒有在"drawable"下找到imageName,將會(huì)返回0return 0;} catch (IllegalAccessException e) {return 0;}} - 
點(diǎn)擊marker顯示信息
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {@Overridepublic boolean onMarkerClick(Marker marker) {//創(chuàng)建InfoWindow展示的viewTextView mark_detail = new TextView(getApplicationContext());Bundle bundle = marker.getExtraInfo();mark_detail.setText(marker.getTitle()+"\n地址:"+bundle.getString("address")+"\n電話:"+bundle.getString("phoneNum"));mark_detail.setTextColor(Color.BLACK);mark_detail.setBackgroundColor(Color.BLUE);//定義用于顯示該InfoWindow的坐標(biāo)點(diǎn)LatLng pt = marker.getPosition();//創(chuàng)建InfoWindow , 傳入 view, 地理坐標(biāo), y 軸偏移量InfoWindow mInfoWindow = new InfoWindow(mark_detail, pt, -100);//顯示InfoWindowmBaiduMap.showInfoWindow(mInfoWindow);return false;}}); 
路徑追蹤
- 
構(gòu)建列表存儲(chǔ)折線點(diǎn)坐標(biāo)
// 構(gòu)造折線點(diǎn)坐標(biāo) List<LatLng> points = new ArrayList<LatLng>(); - 
開始運(yùn)動(dòng)start后,每次獲得定位結(jié)果,記錄與上個(gè)點(diǎn)相隔的距離,計(jì)入運(yùn)動(dòng)總距離,將該點(diǎn)加入列表,使用OverlayOptions將形成的折線(Polyline)列表在地圖上顯示。
public class MyLocationListener implements BDLocationListener {@Overridepublic void onReceiveLocation(BDLocation location) {//Receive Location...MyLatLng = new LatLng(location.getLatitude(),location.getLongitude());if((int)start.getTag()==1){if(points.size()>0){distance = distance + (float)Math.round(DistanceUtil.getDistance(MyLatLng,points.get(points.size()-1))/1000*100)/100;distance_view.setText("距離: "+ distance +"公里");}points.add(MyLatLng);if(points.size()>=2){OverlayOptions ooPolyline = new PolylineOptions().width(10).color(Color.BLACK).points(points);//添加在地圖中mBaiduMap.addOverlay(ooPolyline);}} 
效果
總結(jié)
以上是生活随笔為你收集整理的Android计步器悦步——百度地图的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: CodeForces 901D Weig
 - 下一篇: CodeForces 1491G Swi