最近公司提了一个小case,因为公司物流师傅配送完货物后,通常回仓库都是空车,而这是严重的资源浪费,所以领导就给了一个小case,实时定位司机路线,先建立司机行车档案,在考虑其他业务,反正也是比较空,就随便写了下,没什么太多的功能,就随机记录个demo吧,用的是百度地图的SDK
需求很简单,就是司机打开APP后APP在手机后台传递数据,没有操作页面,其他功能暂时搁置了,先建立档案,很简单的一个case。
首先先集成百度地图的SDK吧,把百度的SDK下载下来放到项目的libs里,然后根据说明在app的build里加上
implementation files('libs/BaiduLBS_Android.jar')
这样就可以了,集成后我们就可以开始下一步工作了
既然要在手机后台运行肯定要用到service了,service用法跟activity很类似,就是生命周期有所不同,再加上没有界面操作。如果有不懂的可以先搜索看看service用法。因为方法比较简单,百度也有说明我就不一一说明了,整个Service如下
package com.example.mypathtailafter;
import android.app.Service;
import android.content.Intent;
import android.os.BatteryManager;
import android.os.IBinder;
import android.util.Log;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import java.util.ArrayList;
import java.util.List;
public class MyService extends Service {
private List<AddressMessageBean> addressMessageBeanList = new ArrayList<>();
private static final String TAG = "MyService";
LocationClient locationClient;
@Override
public void onCreate() {
Log.e(TAG, "onCreate: ");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: ");
initLocationOption();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void initLocationOption() {
//定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动
locationClient = new LocationClient(getApplicationContext());
//声明LocationClient类实例并配置定位参数
LocationClientOption locationOption = new LocationClientOption();
MyLocationListener myLocationListener = new MyLocationListener();
//注册监听函数
locationClient.registerLocationListener(myLocationListener);
//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
locationOption.setCoorType("gcj02");
//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
locationOption.setScanSpan(10000);
//可选,设置是否需要地址信息,默认不需要
locationOption.setIsNeedAddress(true);
//可选,设置是否需要地址描述
locationOption.setIsNeedLocationDescribe(true);
//可选,设置是否需要设备方向结果
locationOption.setNeedDeviceDirect(true);
//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
locationOption.setLocationNotify(false);
//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
locationOption.setIgnoreKillProcess(false);
//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
locationOption.setIsNeedLocationDescribe(true);
//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
locationOption.setIsNeedLocationPoiList(true);
//可选,默认false,设置是否收集CRASH信息,默认收集
locationOption.SetIgnoreCacheException(false);
//可选,默认false,设置是否开启Gps定位
locationOption.setOpenGps(true);
//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
locationOption.setIsNeedAltitude(true);
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
// locationOption.setOpenAutoNotifyMode();
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
// locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
locationClient.setLocOption(locationOption);
//开始定位
locationClient.start();
}
/**
* 实现定位回调
*/
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
//获取纬度信息
double latitude = location.getLatitude();
//获取经度信息
double longitude = location.getLongitude();
//获取定位精度,默认值为0.0f
float radius = location.getRadius();
//获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
String coorType = location.getCoorType();
//获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
int errorCode = location.getLocType();
//获取海拔
double elevation = location.getAltitude();
//获取速度
float speed = location.getSpeed();
//加速度
// String accelerated_speed=location.getsp
//加速度方向
float acceleratio_direction = location.getDirection() ;
Log.e(TAG, "onReceiveLocation: "+errorCode );
AddressMessageBean addressMessageBean = new AddressMessageBean();
addressMessageBean.setLatitude(latitude);
addressMessageBean.setLongitude(longitude);
addressMessageBean.setElevation(elevation);
addressMessageBean.setAcceleratio_direction(acceleratio_direction);
addressMessageBean.setSpeed(speed);
addressMessageBean.setTime(System.currentTimeMillis() + "");
addressMessageBeanList.add(addressMessageBean);
pushDataToServe();
}
}
private void pushDataToServe(){
for (int i=0;i<addressMessageBeanList.size();i++){
Log.e(TAG, "pushDataToServe: "+addressMessageBeanList.get(i).getTime());
addressMessageBeanList.remove(i);
addressMessageBeanList.notifyAll();
}
}
@Override
public void onDestroy() {
super.onDestroy();
locationClient.stop();
}
}
然后在MainActivitie调用
最后可千万不能忘了在AndroidManifest注册服务哦
最后看看打印的数据,十秒打印一条数据,很正常,嗯,完毕
demo地址:https://github.com/cuiyongtao/MyPathTailAfter
csdn下载地址:https://download.csdn.net/download/qq_34163551/11072021
最后说明,我这里并没有做保活处理,但是简单说一下思路吧,可以加个全局广播监听,在固定时间内广播通知startservice一次,因为starservice多次的话也只会有一个实例,完全不用担心会有影响,这样可以增加service存活率。
over