1.创建鹰眼服务
创建服务
获取到服务ID158542
2.下载demo
1)Androidmanifest.xml权限,ak
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<application >
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="tGb2SGaEsKcG2MzxQ9jTzRxl2ZGgGTGb"/>
<service
android:name="com.baidu.trace.LBSTraceService"
android:enabled="true"
android:exported="true"
android:process=":remote"
/>
</application>
2)加入库jar和so
把so库libBaiduMapSDK_base_v4_2_1.so,libBaiduMapSDK_map_v4_2_1.so
libBaiduTraceSDK_v3_0_7.so放入libs/armeabi目录下
jar包BaiduLBS_Android.jar,BaiduTraceSDK_V3_0_7.jar
bos-android-sdk-1.0.3.jar,okhttp-3.8.1.jar,okio-1.13.0.jar放入libs目录下
在build.gradle里添加
sourceSets {
main {
jniLibs.srcDir 'libs'
}
}
3)TrackApplication.java
添加service_id
com.baidu.track目录下的TrackApplication.java
/**
* 轨迹服务ID
*/
public long serviceId = 158542;
// 初始化轨迹服务客户端
LBSTraceClient mClient = new LBSTraceClient(mContext);
// 初始化轨迹服务
Trace mTrace mTrace = new Trace(serviceId, entityName);
4)TracingActivity.java轨迹追踪
com.baidu.track.activity
//开启鹰眼服务,启动鹰眼 service
trackApp.mClient.startTrace(trackApp.mTrace, traceListener);
开启轨迹采集,启动轨迹追踪。至此,正式开启轨迹追踪
trackApp.mClient.startGather(traceListener)
5)结束轨迹追踪
停止轨迹服务:此方法将同时停止轨迹服务和轨迹采集,完全结束鹰眼轨迹服务。
若需再次启动轨迹追踪,需重新启动服务和轨迹采集
trackApp.mClient.stopTrace(trackApp.mTrace, traceListener);
停止轨迹采集:此方法将停止轨迹采集,但不停止轨迹服务(即,不再采集轨迹点了,但鹰眼 service 还存活)。
若需再次启动轨迹追踪,直接调用mTraceClient.startGather()方法开启轨迹采集即可,无需再次启动轨迹服务。此方式可应用于频繁中断轨迹追踪的场景,可避免频繁启动服务
trackApp.mClient.stopGather(traceListener);
3.服务保活
Android系统对应用长时间运行的要求日趋严格,轨迹追踪应用可能会被系统杀死,导致轨迹上传不完整
4.Android 鹰眼 后台启动轨迹追踪采集
直接通过Service后台运行采集gps数据
public class TrackService extends Service {
/**
* 轨迹客户端
*/
public LBSTraceClient mClient = null;
/**
* 轨迹服务
*/
public Trace mTrace = null;
/**
* 轨迹服务ID
*/
public long serviceId = 158542;
/**
* Entity标识
*/
public String entityName = "LYY";
//定位周期单位秒
int gatherInterval = 5;
//打包回传周期,单位秒
int packInterval = 10;
/**
* 轨迹服务监听器
*/
private OnTraceListener traceListener = null;
private LocRequest locRequest = null;
private PowerManager.WakeLock wakeLock = null;
private TrackReceiver trackReceiver = null;
private PowerManager powerManager = null;
static class RealTimeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
public TrackService() {
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
Log.i("bshui","service---onCreate-------");
//1.初始化轨迹服务
// 初始化轨迹服务客户端
mClient = new LBSTraceClient(getApplicationContext());
// 初始化轨迹服务
mTrace = new Trace(serviceId, entityName);
//2.设置定位和回传周期
//自定义定位频率和打包回传频率,频率可设置范围为:2~300秒。
// 例如:定位频率为5s,打包回传频率为10s,则2次定位后打包回传一次
mClient.setInterval(gatherInterval,packInterval);
//3)开启轨迹追踪
//开启鹰眼服务,启动鹰眼 service
mClient.startTrace(mTrace,traceListener);
//开启轨迹采集,启动轨迹追踪。至此,正式开启轨迹追踪
mClient.startGather(traceListener);
powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
traceListener = new OnTraceListener(){
/**
* 绑定服务回调接口
* @param i 状态码
* @param s 消息0,成功,1失败
*/
@Override
public void onBindServiceCallback(int i, String s) {
Log.i("bshui","onBindServiceCallback errorNo:"+i+
" message"+s);
}
/**
* 开启服务回调接口
* @param i 状态码
* @param s 消息
* <pre>10000:请求发送失败</pre>
* <pre>10001:服务开启失败</pre>
* <pre>10002:参数错误</pre>
* <pre>10003:网络连接失败</pre>
* <pre>10004:网络未开启</pre>
* <pre>10005:服务正在开启</pre>
* <pre>10006:服务已开启</pre>
*/
@Override
public void onStartTraceCallback(int i, String s) {
if(i==0 || i>=10003){
//注册广播(电源锁,GPS状态)
if (null == wakeLock) {
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "track upload");
}
if (null == trackReceiver) {
trackReceiver = new TrackReceiver(wakeLock);
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(StatusCodes.GPS_STATUS_ACTION);
getApplication().registerReceiver(trackReceiver, filter);
}
Log.i("bshui","onStartTraceCallback errorNo:"+i+
" message"+s);
}
/**
* 停止服务回调接口
* @param i 状态码
* @param s 消息
* <p>
* <pre>0:成功</pre>
* <pre>11000:请求发送失败</pre>
* <pre>11001:服务停止失败</pre>
* <pre>11002:服务未开启</pre>
* <pre>11003:服务正在停止</pre>
*/
@Override
public void onStopTraceCallback(int i, String s) {
if(i==0 || i==11004){
getApplication().unregisterReceiver(trackReceiver);
}
Log.i("bshui","onStopTraceCallback errorNo:"+i+
" message"+s);
}
@Override
public void onStartGatherCallback(int i, String s) {
Log.i("bshui","onStartGatherCallback errorNo:"+i+
" message"+s);
}
@Override
public void onStopGatherCallback(int i, String s) {
Log.i("bshui","onStopGatherCallback errorNo:"+i+
" message"+s);
}
@Override
public void onInitBOSCallback(int i, String s) {
Log.i("bshui","onInitBOSCallback:errorNo:"+i+
" message:"+s);
}
@Override
public void onPushCallback(byte b, PushMessage pushMessage) {
}
};
// 在Android 6.0及以上系统,若定制手机使用到doze模式,请求将应用添加到白名单。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getApplicationContext().getPackageName();
boolean isIgnoring = powerManager.isIgnoringBatteryOptimizations(packageName);
if (!isIgnoring) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
try {
startActivity(intent);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
//开启鹰眼服务,启动鹰眼 service
mClient.startTrace(mTrace,traceListener);
//开启轨迹采集,启动轨迹追踪。至此,正式开启轨迹追踪
mClient.startGather(traceListener);
}
}
5.轨迹查询和实时监控
public class MainActivity extends AppCompatActivity {
private MapView mapView = null;
private BaiduMap mBaiduMap = null;
private MapStatus mapStatus = null;
private Marker mMoveMarker = null;
private Button btSearch;
private Button btTrack;
private boolean isTrack=true;
/**
* 路线覆盖物
*/
public Overlay polylineOverlay = null;
private AtomicInteger mSequenceGenerator = new AtomicInteger();
/**
* 轨迹点集合
*/
private List<LatLng> trackPoints = new ArrayList<>();
/**
* 历史轨迹请求
*/
private HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest();
/**
* 轨迹客户端
*/
public LBSTraceClient mClient = null;
/**
* 轨迹服务
*/
public Trace mTrace = null;
/**
* 轨迹服务ID
*/
public long serviceId = 158542;
/**
* Entity标识
*/
public String entityName = "LYY"; //LYY
/**
* 轨迹监听器(用于接收历史轨迹回调)
*/
private OnTrackListener mTrackListener = null;
//定位周期单位秒
int gatherInterval = 5;
//打包回传周期,单位秒
int packInterval = 10;
//开始时间(Unix时间戳)
int startTime = (int) (System.currentTimeMillis() / 1000 - 12 * 60 * 60);
//结束时间(Unix时间戳)
int endTime = (int) (System.currentTimeMillis() / 1000);
//分页大小
int pageSize = 1000;
//分页索引
int pageIndex = 1;
private LocRequest locRequest = null;
static class RealTimeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
/**
* 实时定位任务
*/
private RealTimeHandler realTimeHandler = new RealTimeHandler();
private RealTimeLocRunnable realTimeLocRunnable = null;
//Entity 监听器
OnEntityListener entityListener = new OnEntityListener() {
@Override
public void onReceiveLocation(TraceLocation traceLocation) {
super.onReceiveLocation(traceLocation);
if(isTrack) {
double latitude = traceLocation.getLatitude();
double longitude = traceLocation.getLongitude();
LatLng currentLatLng = new LatLng(latitude, longitude);
setMapStatus(currentLatLng, 17.0f);
addMarker(currentLatLng);
}
}
};
class RealTimeLocRunnable implements Runnable {
private int interval = 0;
public RealTimeLocRunnable(int interval) {
this.interval = interval;
}
@Override
public void run() {
mClient.queryRealTimeLoc(locRequest, entityListener);
realTimeHandler.postDelayed(this, interval * 1000);
}
}
/**
* 实时定位任务
*/
public void startRealTimeLoc(int interval){
realTimeLocRunnable = new RealTimeLocRunnable(interval);
realTimeHandler.post(realTimeLocRunnable);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
btSearch = (Button)findViewById(R.id.btSearch);
btTrack = (Button)findViewById(R.id.btTrack);
mapView = (MapView)findViewById(R.id.track_query_mapView);
mBaiduMap = mapView.getMap();
mBaiduMap.setMyLocationEnabled(true);
//1.初始化轨迹服务
// 初始化轨迹服务客户端
mClient = new LBSTraceClient(getApplicationContext());
// 初始化轨迹服务
mTrace = new Trace(serviceId, entityName);
locRequest = new LocRequest(serviceId);
//查询实时定位位置
startRealTimeLoc(packInterval);
//隐藏左下角的logo
View child = mapView.getChildAt(1);
if(child !=null){
child.setVisibility(View.INVISIBLE);
}
//查询轨迹,时间设置为最近12小时
btSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
isTrack = false;
queryHistoryTrack();
}
});
btTrack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mBaiduMap.clear();
mMoveMarker=null;
isTrack = true;
}
});
mTrackListener = new OnTrackListener(){
@Override
public void onHistoryTrackCallback(HistoryTrackResponse response) {
int total = response.getTotal();
if(total == 0){
Toast.makeText(getApplicationContext(),
"没有查到轨迹",
Toast.LENGTH_LONG).show();
}else{
List<TrackPoint> points = response.getTrackPoints();
if(null != points){
for(TrackPoint trackPoint : points){
double latitude = trackPoint.getLocation().getLatitude();
//采集点集合
trackPoints.add(convertTrace2Map(trackPoint.getLocation()));
}
}
if(total > pageSize*pageIndex ){
historyTrackRequest.setPageIndex(++pageIndex);
queryHistoryTrack();
}else{
//SortType:轨迹排序规则
drawHistoryTrack(trackPoints,SortType.asc);
}
}
}
};
}
/**
* 将轨迹坐标对象转换为地图坐标对象
*
* @param traceLatLng
*
* @return
*/
public static LatLng convertTrace2Map(com.baidu.trace.model.LatLng traceLatLng) {
return new LatLng(traceLatLng.latitude, traceLatLng.longitude);
}
/**
* 获取请求标识
*
* @return
*/
public int getTag() {
return mSequenceGenerator.incrementAndGet();
}
/**
* 初始化请求公共参数
*
* @param request
*/
public void initRequest(BaseRequest request) {
request.setTag(getTag());
request.setServiceId(serviceId);
}
/**
* 查询历史轨迹
*/
private void queryHistoryTrack() {
initRequest(historyTrackRequest);
historyTrackRequest.setEntityName(entityName);
historyTrackRequest.setStartTime(startTime);
historyTrackRequest.setEndTime(endTime);
historyTrackRequest.setPageIndex(pageIndex);
historyTrackRequest.setPageSize(pageSize);
// 设置需要纠偏
historyTrackRequest.setProcessed(true);
// 创建纠偏选项实例
ProcessOption processOption = new ProcessOption();
// 设置需要去噪
processOption.setNeedDenoise(true);
// 设置需要抽稀
processOption.setNeedVacuate(true);
// 设置需要绑路
processOption.setNeedMapMatch(true);
// 设置精度过滤值(定位精度大于100米的过滤掉)
processOption.setRadiusThreshold(100);
// 设置交通方式为驾车
processOption.setTransportMode(TransportMode.driving);
// 设置纠偏选项
historyTrackRequest.setProcessOption(processOption);
// 设置里程填充方式为驾车
historyTrackRequest.setSupplementMode(SupplementMode.driving);
mClient.queryHistoryTrack(historyTrackRequest, mTrackListener);
}
public void setMapStatus(LatLng point, float zoom) {
MapStatus.Builder builder = new MapStatus.Builder();
mapStatus = builder.target(point).zoom(zoom).build();
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
}
/**
* 添加地图覆盖物
*/
public void addMarker(LatLng currentPoint) {
if (null == mMoveMarker) {
OverlayOptions overlayOptions = new MarkerOptions()
.position(currentPoint)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_point))
.draggable(true);
mMoveMarker = (Marker) mBaiduMap.addOverlay(overlayOptions);
return;
}
mMoveMarker.setPosition(currentPoint);
}
public void animateMapStatus(List<LatLng> points) {
if (null == points || points.isEmpty()) {
return;
}
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng point : points) {
builder.include(point);
}
MapStatusUpdate msUpdate = MapStatusUpdateFactory.newLatLngBounds(builder.build());
mBaiduMap.animateMapStatus(msUpdate);
}
public void animateMapStatus(LatLng point, float zoom) {
MapStatus.Builder builder = new MapStatus.Builder();
mapStatus = builder.target(point).zoom(zoom).build();
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(mapStatus));
}
/**
* 绘制历史轨迹
*/
public void drawHistoryTrack(List<LatLng> points, SortType sortType) {
// 绘制新覆盖物前,清空之前的覆盖物
mBaiduMap.clear();
if (points == null || points.size() == 0) {
if (null != polylineOverlay) {
polylineOverlay.remove();
polylineOverlay = null;
}
return;
}
if (points.size() == 1) {
OverlayOptions startOptions = new MarkerOptions()
.position(points.get(0))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_start))
.zIndex(9).draggable(true);
mBaiduMap.addOverlay(startOptions);
animateMapStatus(points.get(0), 16.0f);
return;
}
LatLng startPoint;
LatLng endPoint;
if (sortType == SortType.asc) {
startPoint = points.get(0);
endPoint = points.get(points.size() - 1);
} else {
startPoint = points.get(points.size() - 1);
endPoint = points.get(0);
}
// 添加起点图标
OverlayOptions startOptions = new MarkerOptions()
.position(startPoint)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_start))
.zIndex(9).draggable(true);
// 添加终点图标
OverlayOptions endOptions = new MarkerOptions().position(endPoint)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_end))
.zIndex(9).draggable(true);
// 添加路线(轨迹)
OverlayOptions polylineOptions = new PolylineOptions().width(10)
.color(Color.BLUE).points(points);
mBaiduMap.addOverlay(startOptions);
mBaiduMap.addOverlay(endOptions);
polylineOverlay = mBaiduMap.addOverlay(polylineOptions);
OverlayOptions markerOptions =
new MarkerOptions()
.flat(true)
.anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.icon_point))
.position(points.get(points.size() - 1));
// .rotate((float) CommonUtil.getAngle(points.get(0), points.get(1)));
mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions);
animateMapStatus(points);
}
}
6.Demo