您的位置:首页 > 移动开发 > Android开发

使用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 gps 轨迹数据