SDKInitializer.initialize(getApplicationContext());
更换定位图标的方法:
mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo); // 自定义图标
// mCurrentMarker =null ; // 默认图标
mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
定位模式:
private LocationMode mCurrentMode;
mCurrentMode = LocationMode.NORMAL; // 普通模式
// mCurrentMode = LocationMode.FOLLOWING; // 跟随模式
// mCurrentMode = LocationMode.COMPASS; // 罗盘模式
mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker));
初始化:
// 地图初始化
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 定位初始化
mLocClient = new LocationClient(this);
mLocClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 打开gps
option.setCoorType(“bd09ll”); // 设置坐标类型
option.setScanSpan(5000);
mLocClient.setLocOption(option);
mLocClient.start();
setScanSpan是定位时间间隔(ms),setCoorType坐标类型分为三种:
bd09ll 百度加密经纬度坐标
bd09 百度加密墨卡托坐标
gcj02 国测局加密经纬度坐标
定位SDK监听函数:
public class MyLocationListenner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || mMapView == null)
return;
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mBaiduMap.setMyLocationData(locData);
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
}
public void onReceivePoi(BDLocation poiLocation) {
}
}
复写onPause,onResume,onDestory:
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}
@Override
protected void onDestroy() {
// 退出时销毁定位
mLocClient.stop();
// 关闭定位图层
mBaiduMap.setMyLocationEnabled(false);
mMapView.onDestroy();
mMapView = null;
super.onDestroy();
}
在 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;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.util.EncodingUtils;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/34bb1b7bb683b3d85f8e7ed2ba75f46f.jpeg)
总结
作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
OPPO等大厂,18年进入阿里一直到现在。**
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-HjLjd0vN-1713016588339)]
[外链图片转存中…(img-VnTjVDsq-1713016588340)]
[外链图片转存中…(img-2Xmy5Wep-1713016588340)]
[外链图片转存中…(img-3m1wWGNY-1713016588340)]
[外链图片转存中…(img-NmvxFVKr-1713016588340)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/34bb1b7bb683b3d85f8e7ed2ba75f46f.jpeg)
总结
作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!
[外链图片转存中…(img-RS6JlTOp-1713016588341)]
[外链图片转存中…(img-frKD6k4Y-1713016588341)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!