Android 使用百度LBS SDK,Android进程保活黑科技实现原理解密及方法

在 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文件中要加入需要的权限:

到此就大功告成了。

记录轨迹思路
  1. 用Service获取经纬度,onCreate中开始采集经纬度点,保存到ArrayList

  2. 每隔5秒取样一次,若经纬度未发生变化,丢弃该次取样

  3. 在onDestroy中,将ArrayList转成JSON格式,然后存储到SDCard中

显示轨迹思路
  1. 读取目录下所有轨迹文件,并生成ListView

  2. 在OnItemClick中将文件名称通过intent.putExtra传递给显示轨迹的Activity

  3. 根据文件名将对应的JSON内容转成ArrayList

  4. 然后将以上ArrayList的点集依次连线,并绘制到百度地图上

  5. 设置起始点Marker,Zoom级别,中心点为起始点

  6. 轨迹点小于2个无法绘制轨迹,给出提示

初步Demo效果图,获取的经纬度有偏移,明天看看哪里的问题:

LBS

先贴一个保存经纬度点的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();

}

}

}

}

优化轨迹平滑度:

同一数据,优化前后效果对比:

LBS

优化算法:

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移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

总结

最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

这里附上我整理的几十套腾讯、字节跳动,京东,小米,头条、阿里、美团等公司19年的Android面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在GitHub可以见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 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架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

技术进阶之路很漫长,一起共勉吧~

  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值