综述:
今天公司让我做一个APP下百度地图,显示当前用户位置和附近加油站,同时可以搜索公交车方案。刚开始听说这样的需求我有点纠结,因为这个加油站的数据去哪弄,公交搜索我知道肯定容易。所以开始找资料……。后来发现百度地图的搜附近可以解决这个问题。所以废话不多说开始Code,工作时间快速记录。不浪费时间
一.准备:
首先下载百度地图 Android SDK,和定位SDK。百度新的API中将定位部分独立出来了。本别下载下来配置到自己的项目中。
配置好lib就开始,新建两个类,一个是位置监听和显示,用于监听位置变化。还有一个就是查询监听,用于处理查询返回的结果。MyLocationListener类用于监听位置变化,实现BDLocationListener
1 import android.util.Log; 2 3 import com.baidu.location.BDLocation; 4 import com.baidu.location.BDLocationListener; 5 import com.baidu.mapapi.map.LocationData; 6 import com.baidu.mapapi.map.MapView; 7 import com.baidu.mapapi.map.MyLocationOverlay; 8 import com.baidu.platform.comapi.basestruct.GeoPoint; 9 10 /** 11 * 位置监听处理 12 * @author egojit 13 * 14 */ 15 public class MyLocationListener implements BDLocationListener { 16 17 private static String LOG_TAG = "MyLocationListener"; 18 private MapView mMapView; 19 private Context MyContext; 20 21 public MyLocationListener(MapView view, Context context) { 22 this.mMapView = view; 23 this.MyContext = context; 24 } 25 26 @Override 27 public void onReceiveLocation(BDLocation location) { 28 if (location == null) 29 return; 30 31 MyLocationOverlay myLocationOverlay = new MyLocationOverlay( 32 this.mMapView); 33 34 LocationData locData = new LocationData(); 35 // 手动将位置源置为天安门,在实际应用中,请使用百度定位SDK获取位置信息,要在SDK中显示一个位置,需要使用百度经纬度坐标(bd09ll) 36 locData.latitude = location.getLatitude(); 37 locData.longitude = location.getLongitude(); 38 locData.direction = 2.0f; 39 myLocationOverlay.setData(locData); 40 if (mMapView != null && mMapView.getOverlays() != null) { 41 mMapView.getOverlays().add(myLocationOverlay); 42 mMapView.refresh(); 43 mMapView.getController().animateTo( 44 new GeoPoint((int) (locData.latitude * 1e6), 45 (int) (locData.longitude * 1e6))); 46 mMapView.getController().setZoom(16); 47 MainActivity activity = (MainActivity) MyContext; 48 49 activity.jd = locData.longitude; 50 activity.wd = locData.latitude; 51 } 52 53 StringBuffer sb = new StringBuffer(256); 54 sb.append("time : "); 55 sb.append(location.getTime()); 56 sb.append("\nerror code : "); 57 sb.append(location.getLocType()); 58 sb.append("\nlatitude : "); 59 sb.append(location.getLatitude()); 60 sb.append("\nlontitude : "); 61 sb.append(location.getLongitude()); 62 sb.append("\nradius : "); 63 sb.append(location.getRadius()); 64 if (location.getLocType() == BDLocation.TypeGpsLocation) { 65 sb.append("\nspeed : "); 66 sb.append(location.getSpeed()); 67 sb.append("\nsatellite : "); 68 logMsg("GPS定位"); 69 sb.append(location.getSatelliteNumber()); 70 } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { 71 sb.append("\naddr : "); 72 logMsg("winfi定位"); 73 sb.append(location.getAddrStr()); 74 } 75 76 logMsg(sb.toString()); 77 } 78 79 public void onReceivePoi(BDLocation poiLocation) { 80 if (poiLocation == null) { 81 return; 82 } 83 StringBuffer sb = new StringBuffer(256); 84 sb.append("Poi time : "); 85 sb.append(poiLocation.getTime()); 86 sb.append("\nerror code : "); 87 sb.append(poiLocation.getLocType()); 88 sb.append("\nlatitude : "); 89 sb.append(poiLocation.getLatitude()); 90 sb.append("\nlontitude : "); 91 sb.append(poiLocation.getLongitude()); 92 sb.append("\nradius : "); 93 sb.append(poiLocation.getRadius()); 94 if (poiLocation.getLocType() == BDLocation.TypeNetWorkLocation) { 95 sb.append("\naddr : "); 96 sb.append(poiLocation.getAddrStr()); 97 } 98 if (poiLocation.hasPoi()) { 99 sb.append("\nPoi:"); 100 sb.append(poiLocation.getPoi()); 101 } else { 102 sb.append("noPoi information"); 103 } 104 logMsg(sb.toString()); 105 } 106 107 /** 108 * 打日志 109 * 110 * @param s 111 */ 112 private static void logMsg(String s) { 113 Log.i(LOG_TAG, s); 114 } 115 }
MySearchListener查询监听类实现了MKSearchListener接口
1 package com.egojit.dcdemo; 2 3 import android.app.Activity; 4 import android.app.AlertDialog; 5 import android.app.Dialog; 6 import android.content.Context; 7 import android.widget.Toast; 8 9 import com.baidu.mapapi.map.MKEvent; 10 import com.baidu.mapapi.map.MapView; 11 import com.baidu.mapapi.map.PoiOverlay; 12 import com.baidu.mapapi.search.MKAddrInfo; 13 import com.baidu.mapapi.search.MKBusLineResult; 14 import com.baidu.mapapi.search.MKDrivingRouteResult; 15 import com.baidu.mapapi.search.MKPoiInfo; 16 import com.baidu.mapapi.search.MKPoiResult; 17 import com.baidu.mapapi.search.MKSearchListener; 18 import com.baidu.mapapi.search.MKShareUrlResult; 19 import com.baidu.mapapi.search.MKSuggestionResult; 20 import com.baidu.mapapi.search.MKTransitRouteResult; 21 import com.baidu.mapapi.search.MKWalkingRouteResult; 22 23 /** 24 * 查询监听 25 * @author egojit 26 * 27 */ 28 public class MySearchListener implements MKSearchListener { 29 30 private Context contxt; 31 private MapView mMapView; 32 33 public MySearchListener(Context context, MapView mMapView) { 34 this.contxt = context; 35 this.mMapView = mMapView; 36 } 37 38 @Override 39 public void onGetAddrResult(MKAddrInfo result, int iError) { 40 // 返回地址信息搜索结果 41 } 42 43 @Override 44 public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) { 45 // 返回驾乘路线搜索结果 46 } 47 48 @Override 49 public void onGetPoiResult(MKPoiResult result, int type, int iError) { 50 // 返回poi搜索结果 51 52 if (iError == MKEvent.ERROR_RESULT_NOT_FOUND) { 53 Toast.makeText(contxt, "抱歉,未找到结果", Toast.LENGTH_LONG).show(); 54 } else if (iError != 0 || result == null) { 55 Toast.makeText(contxt, "搜索出错啦..", Toast.LENGTH_LONG).show(); 56 } 57 58 PoiOverlay poiOverlay = new PoiOverlay((Activity) contxt, mMapView); 59 poiOverlay.setData(result.getAllPoi()); 60 mMapView.getOverlays().clear(); 61 mMapView.getOverlays().add(poiOverlay); 62 mMapView.refresh(); 63 for (MKPoiInfo info : result.getAllPoi()) { 64 if (info.pt != null) { 65 mMapView.getController().animateTo(info.pt); 66 break; 67 } 68 } 69 70 } 71 72 @Override 73 public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) { 74 // 返回公交搜索结果 75 String plan = "目前公交方案有:\n"; 76 for (int i = 0; i < result.getNumPlan(); i++) { 77 plan += (i + 1) + "." + result.getPlan(i).getContent() + "\n"; 78 } 79 Dialog alertDialog = new AlertDialog.Builder(contxt).setTitle("查询结果") 80 .setMessage(plan).setIcon(R.drawable.ic_launcher).create(); 81 82 alertDialog.show(); 83 } 84 85 @Override 86 public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) { 87 // 返回步行路线搜索结果 88 } 89 90 @Override 91 public void onGetBusDetailResult(MKBusLineResult result, int iError) { 92 // 返回公交车详情信息搜索结果 93 } 94 95 @Override 96 public void onGetShareUrlResult(MKShareUrlResult result, int type, int error) { 97 // 在此处理短串请求返回结果. 98 } 99 100 @Override 101 public void onGetPoiDetailSearchResult(int arg0, int arg1) { 102 // TODO Auto-generated method stub 103 104 } 105 106 @Override 107 public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) { 108 // TODO Auto-generated method stub 109 110 } 111 }
这两个是主要的类。
获取位置和网络连接都是需要相关权限的。我们知道百度LBS是三种技术的综合。GPS定位,wifi定位,基站定位。所这这些权限都是要加入AndroidManifest.xml
1 <!-- 使用网络功能所需权限 --> 2 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > 3 </uses-permission> 4 <uses-permission android:name="android.permission.INTERNET" > 5 </uses-permission> 6 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > 7 </uses-permission> 8 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > 9 </uses-permission> 10 <!-- SDK离线地图和cache功能需要读写外部存储器 --> 11 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > 12 </uses-permission> 13 <uses-permission android:name="android.permission.WRITE_SETTINGS" > 14 </uses-permission> 15 <!-- 获取设置信息和详情页直接拨打电话需要以下权限 --> 16 <uses-permission android:name="android.permission.READ_PHONE_STATE" > 17 </uses-permission> 18 <uses-permission android:name="android.permission.CALL_PHONE" > 19 </uses-permission> 20 <!-- 使用定位功能所需权限,demo已集成百度定位SDK,不使用定位功能可去掉以下6项 --> 21 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" > 22 </uses-permission> 23 24 <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" > 25 </permission> 26 27 <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" > 28 </uses-permission> 29 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" > 30 </uses-permission> 31 <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" > 32 </uses-permission> 33 <uses-permission android:name="android.permission.ACCESS_GPS" /> 34 <uses-permission android:name="android.permission.READ_LOGS"></uses-permission> 35 36 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
还有定位不可缺少的一个服务要加入AndroidManifest.xml中:
1 <service 2 android:name="com.baidu.location.f" 3 android:enabled="true" 4 android:process=":remote" > 5 <intent-filter> 6 <action android:name="com.baidu.location.service_v2.2" > 7 </action> 8 </intent-filter> 9 </service>
这样基本完成:
运行结果如下:进入看到我的位置
点击搜索加油站:
这些红点就是附近的加油站。
点击到市府广场:
可以看到有5个公交乘车方案。
总结:这样技术层面是没有任何问题了。将这些功能嵌入到公司的项目中就可以了。