在 AndroidManifest.xml中声明Service,这一步很关键,不写则无法定位:
<service
android:name=“com.baidu.location.f”
android:enabled=“true”
android:process=“:remote” >
当然,Key也是不可或缺,而且必须正确的:
<meta-data
android:name=“com.baidu.lbsapi.API_KEY”
android:value=“************************” />
最后,在AndroidManifest.xml文件中要加入需要的权限:
到此就大功告成了。
记录轨迹思路
-
用Service获取经纬度,onCreate中开始采集经纬度点,保存到ArrayList
-
每隔5秒取样一次,若经纬度未发生变化,丢弃该次取样
-
在onDestroy中,将ArrayList转成JSON格式,然后存储到SDCard中
显示轨迹思路
-
读取目录下所有轨迹文件,并生成ListView
-
在OnItemClick中将文件名称通过intent.putExtra传递给显示轨迹的Activity
-
根据文件名将对应的JSON内容转成ArrayList
-
然后将以上ArrayList的点集依次连线,并绘制到百度地图上
-
设置起始点Marker,Zoom级别,中心点为起始点
-
轨迹点小于2个无法绘制轨迹,给出提示
初步Demo效果图,获取的经纬度有偏移,明天看看哪里的问题:
先贴一个保存经纬度点的Service的核心代码:
public class RouteRecordService extends Service {
private LocationClient mLocationClient;
private final String ROUTE_PATH = “/sdcard/Route/”;
private String startTime = “”;
private String stopTime = “”;
private List list = new ArrayList();
private RouteAdapter adapter = new RouteAdapter();
private int startId = 1; // 轨迹点初始ID
private int defaultDelay = 5000; // 轨迹点取样间隔时间:ms
private final static double ERROR_CODE = 55.555;
private double routeLng;
private double routeLat;
private boolean isEncrypt = false; // true:读取百度加密经纬度 false:读取设备提供经纬度
private boolean isDebug = true;
// 设备定位经纬度
private enum DeviceLocType {
LATITUDE, LONGITUDE
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
InitLocation(LocationMode.Hight_Accuracy, “gcj02”, 1000, false);
// 初始化路径
File filestoreMusic = new File(ROUTE_PATH);
if (!filestoreMusic.exists()) {
filestoreMusic.mkdir();
}
startTime = getTimeStr();
if (isDebug) {
Toast.makeText(getApplicationContext(), “Start Record Route”,
Toast.LENGTH_SHORT).show();
}
// 开启轨迹记录线程
new Thread(new RouteRecordThread()).start();
}
public class RouteRecordThread implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(defaultDelay);
Message message = new Message();
message.what = 1;
recordHandler.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
final Handler recordHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
startRecordRoute();
}
super.handleMessage(msg);
}
};
private void startRecordRoute() {
// 获取设备经纬度
if (!isEncrypt) {
routeLat = getDeviceLocation(DeviceLocType.LATITUDE);
routeLng = getDeviceLocation(DeviceLocType.LONGITUDE);
if (isDebug)
Toast.makeText(getApplicationContext(),
“Device Loc:” + routeLat + “,” + routeLng,
Toast.LENGTH_SHORT).show();
}
RoutePoint routePoint = new RoutePoint();
if (routeLng != 5.55 && routeLat != 5.55) {
if (list.size() > 0
&& list.get(list.size() - 1).getLat() == routeLat
&& (list.get(list.size() - 1).getLng() == routeLng)) {
if (isDebug) {
// Toast.makeText(getApplicationContext(),
// “Route not change”,
// Toast.LENGTH_SHORT).show();
}
} else {
routePoint.setId(startId++);
routePoint.setLng(routeLng);
routePoint.setLat(routeLat);
list.add(routePoint);
}
}
}
/**
-
获取设备提供的经纬度,Network或GPS
-
@param type
-
请求经度还是纬度
-
@return
*/
private double getDeviceLocation(DeviceLocType type) {
double deviceLat = ERROR_CODE;
double deviceLng = ERROR_CODE;
LocationManager locationManager = (LocationManager) getSystemService(getApplicationContext().LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Location location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
deviceLat = location.getLatitude();
deviceLng = location.getLongitude();
} else {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 1000, 0,
new deviceLocationListener());
Location location1 = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location1 != null) {
deviceLat = location1.getLatitude(); // 经度
deviceLng = location1.getLongitude(); // 纬度
}
}
} else {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 1000, 0,
new deviceLocationListener());
Location location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
deviceLat = location.getLatitude(); // 经度
deviceLng = location.getLongitude(); // 纬度
}
}
if (type == DeviceLocType.LATITUDE)
return deviceLat;
else if (type == DeviceLocType.LONGITUDE)
return deviceLng;
else
return ERROR_CODE;
}
/**
-
设备位置监听器
*/
class deviceLocationListener implements LocationListener {
// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// Provider被enable时触发此函数,比如GPS被打开
@Override
public void onProviderEnabled(String provider) {
}
// Provider被disable时触发此函数,比如GPS被关闭
@Override
public void onProviderDisabled(String provider) {
}
// 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
@Override
public void onLocationChanged(Location location) {
// routeLat = location.getLatitude(); // 经度
// routeLng = location.getLongitude(); // 纬度
}
};
private String getTimeStr() {
long nowTime = System.currentTimeMillis();
Date date = new Date(nowTime);
String strs = “” + ERROR_CODE;
try {
SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMdd_HHmmss”);
strs = sdf.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return strs;
}
/**
-
初始化轨迹文件路径和名称
-
@return String
*/
private String getFilePath() {
stopTime = getTimeStr();
String format = “.json”;
if (isDebug)
format = “.txt”;
return ROUTE_PATH + startTime + “-” + stopTime + format;
}
class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// 读取百度加密经纬度
if (isEncrypt) {
routeLng = location.getLongitude();
routeLat = location.getLatitude();
}
}
}
}
优化轨迹平滑度:
同一数据,优化前后效果对比:
优化算法:
public List optimizePoints(List inPoint) {
int size = inPoint.size();
List outPoint;
int i;
if (size < 5) {
return inPoint;
} else {
// Latitude
inPoint.get(0)
.setLat((3.0 * inPoint.get(0).getLat() + 2.0
- inPoint.get(1).getLat() + inPoint.get(2).getLat() - inPoint
.get(4).getLat()) / 5.0);
inPoint.get(1)
.setLat((4.0 * inPoint.get(0).getLat() + 3.0
-
inPoint.get(1).getLat() + 2
-
inPoint.get(2).getLat() + inPoint.get(3).getLat()) / 10.0);
inPoint.get(size - 2).setLat(
(4.0 * inPoint.get(size - 1).getLat() + 3.0
-
inPoint.get(size - 2).getLat() + 2
-
inPoint.get(size - 3).getLat() + inPoint.get(
size - 4).getLat()) / 10.0);
inPoint.get(size - 1).setLat(
(3.0 * inPoint.get(size - 1).getLat() + 2.0
- inPoint.get(size - 2).getLat()
- inPoint.get(size - 3).getLat() - inPoint.get(
size - 5).getLat()) / 5.0);
// Longitude
inPoint.get(0)
.setLng((3.0 * inPoint.get(0).getLng() + 2.0
- inPoint.get(1).getLng() + inPoint.get(2).getLng() - inPoint
.get(4).getLng()) / 5.0);
inPoint.get(1)
.setLng((4.0 * inPoint.get(0).getLng() + 3.0
-
inPoint.get(1).getLng() + 2
-
inPoint.get(2).getLng() + inPoint.get(3).getLng()) / 10.0);
inPoint.get(size - 2).setLng(
(4.0 * inPoint.get(size - 1).getLng() + 3.0
-
inPoint.get(size - 2).getLng() + 2
-
inPoint.get(size - 3).getLng() + inPoint.get(
size - 4).getLng()) / 10.0);
inPoint.get(size - 1).setLng(
(3.0 * inPoint.get(size - 1).getLng() + 2.0
- inPoint.get(size - 2).getLng()
- inPoint.get(size - 3).getLng() - inPoint.get(
size - 5).getLng()) / 5.0);
}
return inPoint;
}
截取轨迹图片并分享
@@ -1,14 +1,24 @@
package com.zms.baidulbs;
+import java.io.File;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
总结
最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
详细整理在GitHub可以见;
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
的负担。**
[外链图片转存中…(img-msHDOpMF-1711295204644)]
[外链图片转存中…(img-0KDE8qiW-1711295204644)]
[外链图片转存中…(img-xmuwBWYv-1711295204645)]
[外链图片转存中…(img-iHH62wqV-1711295204645)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-qQ0EWqsj-1711295204645)]
总结
最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
[外链图片转存中…(img-WKoadlGw-1711295204646)]
详细整理在GitHub可以见;
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
技术进阶之路很漫长,一起共勉吧~