Advertisement

Android百度鹰眼轨迹

阅读量:

作者:短工邦技术部 - 陈文超

以“百度鹰眼轨迹”功能为基础,在外卖配送场景中展示物流路径规划方案。
例如,在实际操作中:

配送员从订单接收开始记录行程数据;
系统实时更新并传输配送路径信息;
用户端可即时查看完整的物流走向;
对于经常使用外卖服务的用户而言,
更为直观地追踪订单动态,
无需 repeatedly call 商户询问订单状态。

最初想到的方法是通过系统持续采集配送员位置数据,并经由服务器接收端接收并存储。随后,在客户端实时更新并展示这些位置信息于地图界面。这种方案虽然看似简单,并且仅涉及数据传输与更新过程。但需要注意的是,在实际运行中可能会出现一些问题:例如当遇到网络环境欠佳时,在移动设备连接不稳定的场景下可能导致导航服务无法正常工作。此时生成的位置坐标可能出现扭曲状态,并且最终导出的地图展示则呈现混乱状态。

系统注意到百度地图已发布鹰眼轨迹服务的SDK。该服务能够追踪某个目标并将其位置实时更新到百度地图上。这正是我们期待的功能。接下来我们将着手开发这一SDK的功能。

需要先在API控制台中创建一个新的Android应用,并明确该应用类型为Android。随后,在配置界面勾选所有相关API设置。值得注意的是,在最近一次操作中新增的应用带来了两个关键参数——‘发布版SHA1’和‘开发板SHA1’这两个指标的引入极大地方便了对调试状态下功能模块的开发。同时解决了因开发者签名SHA1变更导致无法正常初始化SDK的问题

开发版本的SHA1值获取可以在Eclipse环境下直接进行操作。具体步骤为:进入Windows系统偏好设置,在Android构建过程中选择相应的选项。

这里写图片描述

发布版SHA1的获取:
使用keytool
第1步:运行进入控制台

这里写图片描述
这里写图片描述

第2步:定位到.android文件夹下,输入cd .android

这里写图片描述

第3步:运行命令keytool -list -v -keystore并指定路径debug.keystore后,在命令窗口中将看到三种指纹认证的数字证书。根据需求选择SHA1类型数字证书(其密码为Android安全策略),例如:
其中keytool是Java JDK自带的工具;
debug\_keystore则是完整的Android签名证书文件路径。

这里写图片描述
这里写图片描述

当AK创建完成时,在控制台可以获取相应的AK信息...为了实现该目标,在AndroidManifest.xml中应添加必要的配置项

这里写图片描述

请访问http://lbsyun.baidu.com/index.php?title=yingyan/manage并创建鹰眼服务,请获取一个服务ID标识码,并将其用于在代码中启动鹰眼服务系统。

这里写图片描述
这里写图片描述

将开发包导入项目中

这里写图片描述

请前往该页面下载其他Android SDK版本,并根据项目需求选择必要的SDK版本,并避免单独安装每一个SDK以免导致功能冲突

在下载并获取统一 SDK 之后 导入相关.so 文件及.jar 包是必要的步骤 而鹰眼 SDK 则仅需引入.jar 包及-armveabi 即可 这样可以避免 x86 和 x86_64 架构下需要额外加载.so 文件所带来的初始化失败问题 不过 如果需要使用 JPush 极光推送 SDK 则同样仅需引入.jar 包及-armveabi 即可避免与其他库产生冲突 不过 不得不说 百度 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上实现这一功能以及后续的具体操作步骤,则将在后面的章节中详细介绍。

百度鹰眼轨迹

全部评论 (0)

还没有任何评论哟~