标签:
作者:短工邦技术部 - 陈文超
百度地图之百度鹰眼轨迹使用
拿外卖配送为例,配送员从接单开始上传行驶轨迹,用户端可以实时查看配送员的行驶轨迹,对于点外卖的用户来说可以更直接地观察到自己的订单是否在配送过程中,不再需要一遍一遍地拨打商户电话催促。
在思考相关解决方案的时候第一个想到的是在后台不断地获取配送员的经纬度,上传到服务器,然后在用户端实时地刷新这些经纬度数据显示到地图上。这种方法虽说思路很简单,只是数据的上传与刷新,但是轨迹的准确度与定位的精准度有很大关系,如果遇到网络环境较弱等的情况,定位经纬度数据一定是东歪西扭的,显示在地图上的轨迹信息也是横七竖八的。
后台发现百度地图上线了鹰眼轨迹服务的SDK,可以实现对某个对象的轨迹追踪,并显示在百度地图上,看起来就是我们想要的功能,那我们就先来实现这个SDK的功能。
首先得在API控制台创建新的应用,应用类型为Android应用,把全部API都勾上,最近创建新的应用增加了“发布版SHA1”、“开发板SHA1”,大大方便了对于调试状态下的功能开发,以及签名上线后由于签名SHA1的改变而导致无法初始化SDK的问题。
开发版SHA1的获取:
可以在eclipse中直接查看:windows -> preferance -> android -> build
发布版SHA1的获取:
使用keytool
第1步:运行进入控制台
第2步:定位到.android文件夹下,输入cd .android
第3步:输入keytool -list -v -keystore debug.keystore,会得到三种指纹证书,选取SHA1类型的证书(密钥口令是android),例如:
其中keytool为jdk自带工具;debug.keystore为Android 签名证书文件的完整路径
创建成功后可以在控制台得到相应的AK,在工程AndroidManifest.xml需要配置该AK
使用过百度定位功能的同学就知道使用方法了
接下来到http://lbsyun.baidu.com/index.php?title=yingyan/manage
创建鹰眼服务,得到一个服务ID,用于在代码中初始化鹰眼服务
将开发包导入项目中
若使用了百度地图其他的SDK,请到http://lbsyun.baidu.com/index.php?title=androidsdk/sdkandev-download
选择下载在项目中有用到的功能,切记不要单独下载每一个SDK,否则会引起包之间的冲突,这一点被百度坑的心累。
选择下载完统一的SDK后导入相关so文件和jar,鹰眼的SDK只需要导入jar包和armeabi就可以了,x86、x86_64不需要导入,否则百度又会出现初始化失败的问题。若有使用到JPush极光推送的SDK,也只需要导入jar包和armeabi就可以了,否则也会冲突。(真感觉百度的SDK的兼容性真是让人捉急,很容易出现库与库之间的冲突(/”≡ _ ≡)/~┴┴)
接下来可以开始工程的配置了,
首页将第一步创建应用获得的AK配置到AndroidManifest.xml
<application>
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="AK key" />
<service
android:name="com.baidu.trace.LBSTraceService"
android:enabled="true"
android:exported="true" >
</service>
<service
<!-- 我们自己的轨迹服务 -->
android:name="com.mcandmc.xxxxxxx.service.MyService"
android:enabled="true"
android:exported="false"
android:process=":track" >
</service>
</application>
添加各种权限
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--允许程序连接到已配对的蓝牙设备-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--允许程序发现和配对蓝牙设备-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 用于读取手机当前的状态-->
<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" />
<!-- SD卡读取权限,用户写入离线定位数据-->
<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" />
public class MyService extends Service{
private static final String TAG = "MyService";
// 轨迹服务
protected static Trace trace = null;
// 鹰眼服务ID,开发者创建的鹰眼服务对应的服务ID
public static final long serviceId = xxxxxxxx;
// 轨迹服务类型
//0 : 不建立socket长连接,
//1 : 建立socket长连接但不上传位置数据,
//2 : 建立socket长连接并上传位置数据)
private int traceType = 2;
// 轨迹服务客户端
public static LBSTraceClient client = null;
// Entity监听器
public static OnEntityListener entityListener = null;
// 开启轨迹服务监听器
protected OnStartTraceListener startTraceListener = null;
// 停止轨迹服务监听器
protected static OnStopTraceListener stopTraceListener = null;
// 采集周期(单位 : 秒)
private int gatherInterval = 10;
// 设置打包周期(单位 : 秒)
private int packInterval = 20;
protected static boolean isTraceStart = false;
// 手机IMEI号设置为唯一轨迹标记号,只要该值唯一,就可以作为轨迹的标识号,使用相同的标识将导致轨迹混乱
private String imei;
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null && intent.getExtras() != null){
imei= intent.getStringExtra("imei");
}
init();
return super.onStartCommand(intent, START_STICKY, startId);
}
//被销毁时反注册广播接收器
public void onDestroy() {
super.onDestroy();
stopTrace();
}
/**
* 初始化
*/
private void init() {
// 初始化轨迹服务客户端
client = new LBSTraceClient(this);
// 设置定位模式
client.setLocationMode(LocationMode.High_Accuracy);
// 初始化轨迹服务
trace = new Trace(this, serviceId, imei, traceType);
// 采集周期,上传周期
client.setInterval(gatherInterval, packInterval);
// 设置http请求协议类型0:http,1:https
client.setProtocolType(0);
// 初始化监听器
initListener();
// 启动轨迹上传
startTrace();
}
// 开启轨迹服务
private void startTrace() {
// 通过轨迹服务客户端client开启轨迹服务
client.startTrace(trace, startTraceListener);
}
// 停止轨迹服务
public static void stopTrace() {
// 通过轨迹服务客户端client停止轨迹服务
LogUtil.i(TAG, "stopTrace(), isTraceStart : " + isTraceStart);
if(isTraceStart){
client.stopTrace(trace, stopTraceListener);
}
}
// 初始化监听器
private void initListener() {
initOnEntityListener();
// 初始化开启轨迹服务监听器
initOnStartTraceListener();
// 初始化停止轨迹服务监听器
initOnStopTraceListener();
}
/**
* 初始化OnStartTraceListener
*/
private void initOnStartTraceListener() {
// 初始化startTraceListener
startTraceListener = new OnStartTraceListener() {
// 开启轨迹服务回调接口(arg0 : 消息编码,arg1 : 消息内容,详情查看类参考)
public void onTraceCallback(int arg0, String arg1) {
LogUtil.i(TAG, "开启轨迹回调接口 [消息编码 : " + arg0 + ",消息内容 : " + arg1 + "]");
if (0 == arg0 || 10006 == arg0) {
isTraceStart = true;
}
}
// 轨迹服务推送接口(用于接收服务端推送消息,arg0 : 消息类型,arg1 : 消息内容,详情查看类参考)
public void onTracePushCallback(byte arg0, String arg1) {
LogUtil.i(TAG, "轨迹服务推送接口消息 [消息类型 : " + arg0 + ",消息内容 : " + arg1 + "]");
}
};
}
// 初始化OnStopTraceListener
private void initOnStopTraceListener() {
stopTraceListener = new OnStopTraceListener() {
// 轨迹服务停止成功
public void onStopTraceSuccess() {
LogUtil.i(TAG, "停止轨迹服务成功");
isTraceStart = false;
stopSelf();
}
// 轨迹服务停止失败(arg0 : 错误编码,arg1 : 消息内容,详情查看类参考)
public void onStopTraceFailed(int arg0, String arg1) {
LogUtil.i(TAG, "停止轨迹服务接口消息 [错误编码 : " + arg0 + ",消息内容 : " + arg1 + "]");
}
};
}
// 初始化OnEntityListener
private void initOnEntityListener() {
entityListener = new OnEntityListener() {
// 请求失败回调接口
@Override
public void onRequestFailedCallback(String arg0) {method stub
Looper.prepare();
LogUtil.i(TAG, "entity请求失败回调接口消息 : " + arg0);
Toast.makeText(getApplicationContext(), "entity请求失败回调接口消息 : " + arg0, Toast.LENGTH_SHORT).show();
Looper.loop();
}
// 添加entity回调接口
@Override
public void onAddEntityCallback(String arg0) {
Looper.prepare();
LogUtil.i(TAG, "添加entity回调接口消息 : " + arg0);
Toast.makeText(getApplicationContext(), "添加entity回调接口消息 : " + arg0, Toast.LENGTH_SHORT).show();
Looper.loop();
}
// 查询entity列表回调接口
@Override
public void onQueryEntityListCallback(String message) {
LogUtil.i(TAG, "onQueryEntityListCallback : " + message);
}
@Override
public void onReceiveLocation(TraceLocation location) {
}
};
}
}
在Activity中启动Servise
Intent intent = new Intent();
intent.putExtra("imei", "xxxxxx");
intent.setClass(this, MyService.class);
startService(intent);
这样APP就会在后台默默地上传轨迹啦
如果要查看轨迹是否上传成功,可以在轨迹管理台查看,至于如何实现在APP上查询配送员的轨迹将陆续在后面的文章提到。
标签:
原文地址:http://blog.csdn.net/duangongbang/article/details/51320029