使用Android GPS api 实现一个轨迹记录的小功能
2017-10-25 09:08
579 查看
引入
市场上的跑步软件已经是非常多了,如咕咚和悦跑圈还有其他,很多大厂也在涉足这个方面。而最简单的运动跑步,最近几年也因简单,不限场地,运动效果出众备受大众喜欢。我的这篇文章的内容很多也是从网上学习其他的博客内容,外加利用android自身的提供的api实现的,希望能对有这方面需求的朋友有所帮助。
项目地址:https://github.com/Lilee902/RunGps
介绍
先上两张图,界面比较丑,不过一些数据基本都有了,这个图片是临时要用截取的,所以轨迹线很短,之前有实际测过,轨迹线OK的。因为demo是很久之前写的,我的测试手机是5.1的系统,当时并没有做运行时权限判定,如果您的测试环境是在6.0+的话,请注意加上权限判断。
经纬度点的获取是利用android的api LocationManager以及相关的类实现的。
获取到经纬度点展示时使用的百度地图的com.baidu.mapapi.map.MapView这个类做的页面显示(百度地图只做页面显示使用)。
另外,android api 获取到的点是谷歌坐标,需要用百度sdk中的api转化为百度的坐标,然后再做显示,不然位置会整体发生偏移。(火星坐标百度百科 介绍:https://baike.baidu.com/item/%E7%81%AB%E6%98%9F%E5%9D%90%E6%A0%87%E7%B3%BB%E7%BB%9F ,具体介绍,网上也有很多文章)。
主要代码介绍
API 获取经纬度点,不过这样直接获取location,经常获取到的为null,因为这个时候,gps还没有定位成功。if (locationManager == null) { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); } Location location = mActPersenter.getLatLng(locationManager); if (location != null) { firstGetLocation(location); }
大家自然会想到,不能直接获取,那就加listener,三板斧嘛,当然是有加监听的,如下代码,其中 LocationManager.GPS_PROVIDER,LocationManager.NETWORK_PROVIDER 分别为利用手机gps和利用蜂窝网络获取。这里要使用gps,因为蜂窝网络会发生漂移。(如果有朋友只是定位大体位置的话,可以用network,这个效率和速度都会更快)
private LocationManager locationManager; private void initListener() { if (locationManager == null) { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); } locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1,locationGpsListener); }
那么,这个locationGpsListener里面具体要做什么,下面这段代码已经可以基本解答你的疑惑了。
/** * location的监听。 */ private MLocationListener locationGpsListener = new MLocationListener() { // 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 @Override public void onLocationChanged(Location mlocation) { if (mlocation != null) { if (!isPause) {// 如果没有暂停,则记录数据。 if (mMoveGpsDataList != null && mMoveGpsDataList.size() >= 1) { speed = mlocation.getSpeed(); double latitude = mlocation.getLatitude(); double longitude = mlocation.getLongitude(); LatLng latLng = new LatLng(latitude, longitude); Logger.e(LTAG, "B_latLng : " + latLng.latitude + "," + latLng.longitude); //google坐标转百度坐标。 latLng = gpsToBaidu(latLng); PositionBean lastPosition = mMoveGpsDataList.getLast(); // 如果位置和上一次记录的位置点相同,则认为没有移动。 if (lastPosition.latlng.latitude != latLng.latitude || lastPosition.latlng.longitude != latLng.longitude) { // 计算移动距离,和速度。 PositionBean oncePosition = getMoveGpsData(lastPosition, latLng); if (oncePosition == null) { showToast("点漂移了一次!"); } else { mPointListWithGps.add(latLng); mMoveGpsDataList.add(oncePosition); mListGpsLocationAdapter.update(mMoveGpsDataList); updateListenerView(); } } else { Logger.e(LTAG, "未移动,LocationSpeed : " + speed); if (onces % 10 == 0) { showToast("未移动,LocationSpeed : " + speed); onces = 0; } onces++; } } else { firstGetLocation(mlocation); } } else {// 如果暂停了,则toast提示。 showToast("位置改变了一次,暂停状态未记录!"); } } } };
你可能也注意到了,里面有个方法,gpsToBaidu(latLng);这个是应该就是坐标转换的了,具体的实现如下:
/** * 标准的GPS经纬度坐标直接在地图上绘制会有偏移,这是测绘局和地图商设置的加密,要转换成百度地图坐标 * * @return 百度地图坐标 */ public LatLng gpsToBaidu(LatLng data) {// data格式 nmea标准数据 ddmm.mmmmm,ddmm.mmmm // 如3030.90909,11449.1234 // 将GPS设备采集的原始GPS坐标转换成百度坐标 CoordinateConverter converter = new CoordinateConverter(); converter.from(CoordType.GPS); // sourceLatLng待转换坐标 converter.coord(data); LatLng desLatLng = converter.convert(); return desLatLng; }
到这里,好像就介绍的差不多了。只剩下最后一步展示了,这个时候就要用到百度sdk了,当然上面坐标转换也是用百度的,不过也是为这一步做准备的。
private void updateListenerView() { if (mMoveGpsDataList != null && mMoveGpsDataList.size() >= 1) { PositionBean positionBean = mMoveGpsDataList.getLast(); mTvDis.setText("距离 : " + mTotalDistance); mTvV.setText("配速 : " + positionBean.velocity + "m/s"); mTvTimes.setText("时间 : " + getFormatTime(mTotalTimes)); if (mPointListWithGps != null && mPointListWithGps.size() > 1) { mBaiduMap.clear();// 先将地图上的点清除。 // 在地图上画线。 OverlayOptions polylineOption = new PolylineOptions().points(mPointListWithGps) .width(10).color(Color.RED); Polyline mVirtureRoad = (Polyline) mBaiduMap.addOverlay(polylineOption); // 在地图上画起始点。 OverlayOptions markerOptions; markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_positioning_big)) .position(mPointListWithGps.get(0)); Marker mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions); } // 设置当前位置的蓝色的点。 LatLng latLng = positionBean.latlng; if (latLng != null) { MyLocationData locData = new MyLocationData.Builder().accuracy(40) // 此处设置开发者获取到的方向信息,顺时针0-360 .direction(100).latitude(latLng.latitude).longitude(latLng.longitude) .build(); mBaiduMap.setMyLocationData(locData); } } }
结束
用android api 实现跑步基本内容几乎都在这里了。demo中也有一些计算速度距离之类的数据。已经有了经纬度点和每个点之间的时间间隔,相信这些已经就不是什么问题了,都是一些计算。根据需求来就可以了。最后,谢谢大家,希望可以帮到大家,demo不完善,见谅。后期我可能会完善一下。如果错误,望不吝斧正,谢谢。
相关文章推荐
- Android 使用百度鹰眼实现运动轨迹功能
- Android基于各官方API实现分享功能(不使用第三方集成工具)
- Android 使用百度鹰眼实现运动轨迹功能
- Android-使用LitePal实现一个便笺功能
- Android 使用MVP模式 实现一个查询功能。
- Android上实现一个简单的天气预报APP(十四) 使用百度API定位城市
- Android使用百度地图API实现GPS步行轨迹
- 关于Android 使用官方API 实现人脸检测功能
- Android使用百度地图API实现GPS步行轨迹
- 记录一个使用MySql函数实现查找子节点的功能实现
- 使用cookies实现浏览历史记录功能
- 使用Session记录页面地址和实现页面返回功能
- (转)使用一个下拉框或文本框+列表框的方式实现类似IE地址栏自动完成的功能
- 【Android游戏开发十六】Android Gesture之【触摸屏手势识别】操作!利用触摸屏手势实现一个简单切换图片的功能!
- Android应用程序开发教程:实现一个功能比较完善的登录对话框
- 使用android隐藏api实现亮度调节
- Android使用MediaRecorder实现录音功能相关知识
- Android GPS 定位的实现(2-1) 使用Google地图
- 使用cookies实现浏览历史记录功能
- 使用Session记录页面地址和实现页面返回功能