前不久写android应用需要用到轨迹记录,网上找了好多,结合自己看的文档,把这些写出来,给更多人看到,虽然很简单,但还是挺有用的。
主要思路
百度地图显示地图需要使用一个View来显示地图,地图上有一个图层用来显示轨迹,叫 com.baidu.mapapi.map.RouteOverlay,在RouteOverlay上添加路径信息,然后绘制在图层上,再显示出来就好鸟~
使用百度api首先需要申请百度api的key
这里申请,下载百度的sdk
然后就是代码啦
新建一个工程 就叫baduTraceDemo吧 工程配置
把下载的sdk文件里的jar和so库文件解压粗来,把百度定位需要的jar文件放在工程的libs文件夹下,然后在libs文件夹下新建一个文件夹叫 armeabi 把so文件放在这,就像这样
MainActivity里就放一个Button就好了,
MainActivity.java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void OnClick(View v){ switch(v.getId()){ case R.id.startBtn : Intent intent = new Intent(MainActivity.this,LocationOverlay.class); startActivity(intent); break; default : break; } } }
把BaiduMapsApiDemo里面的DemoApplication直接复制过来,把里面的key 改成我们自己申请的
再定义地图显示图层,
public class LocationOverlay extends Activity { /** * 定位间隔 单位毫秒 */ private int seconds = 1000 * 20; /** * 经纬度数组 */ private geoPointArray gpArray ; /** * 定位开始点 */ private GeoPoint start; /** * 定位结束点 */ private GeoPoint end; /** * 定位点的集合 即路径 */ private MKRoute mkRoute; /** * 定位图层 */ private RouteOverlay routeOverlay; // 定位相关 LocationClient mLocClient; LocationData locData = null; public MyLocationListenner myListener = new MyLocationListenner(); MapView mMapView = null; // 地图View /** * 地图控制器 */ private MapController mMapController = null; boolean isFirstLoc = true;//是否首次定位 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 使用地图sdk前需先初始化BMapManager. * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建, * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁 */ DemoApplication app = (DemoApplication)this.getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(getApplicationContext()); /** * 如果BMapManager没有初始化则初始化BMapManager */ app.mBMapManager.init(DemoApplication.strKey,new DemoApplication.MyGeneralListener()); } setContentView(R.layout.activity_locationoverlay); CharSequence titleLable="记录轨迹"; setTitle(titleLable); //地图初始化 mMapView = (MapView)findViewById(R.id.bmapView); mMapController = mMapView.getController(); mMapView.getController().setZoom(14); mMapView.getController().enableClick(true); mMapView.setBuiltInZoomControls(true); //定位初始化 mLocClient = new LocationClient( this ); locData = new LocationData(); mLocClient.registerLocationListener( myListener ); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);//打开gps option.setCoorType("bd09ll"); //设置坐标类型 option.setScanSpan(seconds); // 定位间隔时间 单位毫秒 option.setIsNeedAddress(true); // 需要街道名称信息 option.setNeedDeviceDirect(false); // 不需要方向信息 mLocClient.setLocOption(option); mLocClient.start(); mkRoute = new MKRoute(); routeOverlay = new RouteOverlay(LocationOverlay.this, mMapView); routeOverlay.setData(mkRoute); //添加定位图层 mMapView.getOverlays().add(routeOverlay); //修改定位数据后刷新图层生效 mMapView.refresh(); } /** * 修改位置图标 * @param marker */ public void modifyLocationOverlayIcon(Drawable marker){ //当传入marker为null时,使用默认图标绘制 routeOverlay.setEnMarker(marker); //修改图层,需要刷新MapView生效 mMapView.refresh(); } /** * 定位SDK监听函数 */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location == null) return ; locData.latitude = location.getLatitude(); locData.longitude = location.getLongitude(); //如果不显示定位精度圈,将accuracy赋值为0即可 locData.accuracy = 0; // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。 locData.direction = location.getDerect(); // 是手动触发请求或首次定位时 if (isFirstLoc){ gpArray = new geoPointArray(); start = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)); end = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)); // 把开始点放在路径中 gpArray.addGeoPoint(start); // 构造路径 mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray()); // 定位图层设置路径 routeOverlay.setData(mkRoute); // 更新图层数据执行刷新后生效 mMapView.refresh(); // 移动地图到定位点 mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6))); isFirstLoc = false; }else{ Log.i("test:LocationOverlay","loc:"+location.getLatitude()+","+location.getLongitude()+","+location.getAddrStr()); end = new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6)); // 把当前点放在路径中 gpArray.addGeoPoint(end); // 构造路径 mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray()); // 定位图层设置路径 routeOverlay.setData(mkRoute); // 移动地图到定位点 mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude * 1e6))); // 刷新图层 mMapView.refresh(); } } @Override public void onReceivePoi(BDLocation arg0) { // TODO Auto-generated method stub } } @Override protected void onPause() { mMapView.onPause(); super.onPause(); } @Override protected void onResume() { mMapView.onResume(); super.onResume(); } @Override protected void onDestroy() { //退出时销毁定位 if (mLocClient != null) mLocClient.stop(); mMapView.destroy(); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mMapView.onRestoreInstanceState(savedInstanceState); } } /** * 经纬度数组类 */ class geoPointArray{ private ArrayList <GeoPoint> mlist; geoPointArray(){ mlist = new ArrayList<GeoPoint>(); } public void addGeoPoint(GeoPoint point){ mlist.add(point); } /** * @return 返回包含经纬度点的一纬数组 */ public GeoPoint[] getGeoPointArray(){ GeoPoint []gp = new GeoPoint[mlist.size()]; for(int i=0; i<mlist.size(); i++){ gp[i] = mlist.get(i); } return gp; } }
地图图层的路径信息参数是 com.baidu.mapapi.search.MKRoute,而MKRoute里面还要构造一系列的点来组成路径customizeRoute(GeoPoint st, GeoPoint en, GeoPoint[] passby) 我们就自己写一个类来构造GeoPoint[] passby ,就是上面的geoPointArray,卧槽我研究这个研究了好久的说,当然还要重写监听器 MyLocationListenner,在这个监听器里面没定一次位就把得到的经纬度点添加我geoPointArray里面,
gpArray.addGeoPoint(currentPoint);
重新构造一次路径,再把路径添加到图层上
mkRoute.customizeRoute(start, end, gpArray.getGeoPointArray()); routeOverlay.setData(mkRoute);
最后是ManiFest.xml的填写,把百度需要的权限啊,服务啊,还有key添加上
添加百度的各种权限 ,百度真流氓,给的demo里面还要打电话的权限,这里用不到,就去掉了
<!--使用网络功能所需权限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"> </uses-permission> <uses-permission android:name="android.permission.INTERNET"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"> </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"> </uses-permission> <!-- SDK离线地图和cache功能需要读写外部存储器 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <uses-permission android:name="android.permission.WRITE_SETTINGS"> </uses-permission> <!-- 使用定位功能所需权限,demo已集成百度定位SDK,不使用定位功能可去掉以下6项 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"> </uses-permission> <permission android:name="android.permission.BAIDU_LOCATION_SERVICE"> </permission> <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"> </uses-permission> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"> </uses-permission>
在<application>里面添加这两行,服务权限,和key,自己用的话,记得把里面的key值换掉哦
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="yRLtRhhaGdHuuLXeulWCtjSu"/> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" />
3. 差不多完成了,可以编译试试了,
当然这里写的太简略了,一会把工程放下面,完成之后出去转一圈试试
4.终于写完鸟
卧槽,终于写完鸟,第一次写博客,感觉写博客好难,比写代码麻烦,不知道从哪里开始写,有东西讲不粗来的感觉,看来要好好练练了(OSC肿么没有预览),以后多写博客^_^
代码,还没用osc的git,就先用网盘吧 baiduTraceDemo.zip