调用百度鹰眼api实现实时轨迹绘制

自己想做一个跑步路径轨迹记录的app,刚好百度地图有鹰眼api,就拿过来调用了,这里给出鹰眼api调用的一个完整实现的例子HelloTrace,放在了完整包的下载链接为:http://download.csdn.net/detail/sinat_22013331/9323045

最近缺下载积分,所以需要一个下载币。。只要一个。。


百度鹰眼api接口的实现,在实现之前要进行工程配置,这是第一步,在AndroidManifest.xml文件中配置的信息是

        <meta-data
        	android:name="com.baidu.lbsapi.API_KEY"
        	android:value="百度接入AK" />

    	<service
        	android:name="com.baidu.trace.LBSTraceService"
        	android:enabled="true"
        	android:exported="true" >
    	</service>

这个配置信息要放在<application>的子项里。其中的AK值是需要在百度开发者中心自己做申请的。ak的申请地址是: 点击打开链接

在这个申请的时候需要注意,ak申请的设置里面,安全码的实现是用SHA1和应用的包名组合在一起的,这里要注意packet的名称,一个包名只能对应一个ak值,如果对应的包名不对,就会出现errcode为230的情况,scode有误。

配置过后要把相关的JAR包导进工程里。




第二步:要申请一个鹰眼服务帐号,获得service_id,在主线程中定义这个service_id。




第三步:设置输出界面,在输出界面中包含一个MapView,用来展示实时的trace信息

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.blyang.MainActivity" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        />

</LinearLayout>



第四步:定义初始的变量

    	int gatherInterval = 3;  //位置采集周期 (s)
    	int packInterval = 10;  //打包周期 (s)
    	String entityName = null;  // entity标识
    	long serviceId = 你的service_id;// 鹰眼服务ID
   	int traceType = 2;  //轨迹服务类型
    	private static OnStartTraceListener startTraceListener = null;  //开启轨迹服务监听器
    
	private static MapView mapView = null;
	private static BaiduMap baiduMap = null;
	private static OnEntityListener entityListener = null;
	private RefreshThread refreshThread = null;  //刷新地图线程以获取实时点
	private static MapStatusUpdate msUpdate = null;
	private static BitmapDescriptor realtimeBitmap;  //图标
	private static OverlayOptions overlay;  //覆盖物
	private static List<LatLng> pointList = new ArrayList<LatLng>();  //定位点的集合
	private static PolylineOptions polyline = null;  //路线覆盖物
	
	
    	private Trace trace;  // 实例化轨迹服务
    	private LBSTraceClient client;  // 实例化轨迹服务客户端



第五步:onCreate方法的实现

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		SDKInitializer.initialize(getApplicationContext());
		
		setContentView(R.layout.activity_main);  //设置主界面
		
		init();  //相关变量初始化
		
		initOnEntityListener();  //初始化实体监听器
		
		initOnStartTraceListener();  //初始化轨迹追踪监听器
		
		client.startTrace(trace, startTraceListener);  // 开启轨迹服务
	}




其中init()方法为相关变量的初始化,这个方法体如下:
	/**
	 * 初始化各个参数
	 */
	 private void init() {
		 
		 mapView = (MapView) findViewById(R.id.mapView);
		 baiduMap = mapView.getMap();
		 mapView.showZoomControls(false);
		 
		 entityName = getImei(getApplicationContext());  //手机Imei值的获取,用来充当实体名
		 
         client = new LBSTraceClient(getApplicationContext());  //实例化轨迹服务客户端
         
         trace = new Trace(getApplicationContext(), serviceId, entityName, traceType);  //实例化轨迹服务
         
         client.setInterval(gatherInterval, packInterval);  //设置位置采集和打包周期
	 }




实体监听器的初始化方法为initOnEntityListener()方法,在这个方法中定义实体的相关操作,方法体如下:
	 /**
	  * 初始化设置实体状态监听器
	  */
	 private void initOnEntityListener(){
		 
		 //实体状态监听器
		 entityListener = new OnEntityListener(){

			@Override
			public void onRequestFailedCallback(String arg0) {
				Looper.prepare();
				Toast.makeText(
						getApplicationContext(), 
						"entity请求失败的回调接口信息:"+arg0, 
						Toast.LENGTH_SHORT)
						.show();
				Looper.loop();
			}
			
			@Override
			public void onQueryEntityListCallback(String arg0) {
				/**
				 * 查询实体集合回调函数,此时调用实时轨迹方法
				 */
				showRealtimeTrack(arg0);  
			}
			
		 };
	 }
	 
在其中的查询实体集合的回调方法中,要调用showRealtimeTrack方法,用来展示实时的路径信息,这个方法在下面会详细讲到。




接着,要初始化启动轨迹监听器initOnStartTraceListener,开启运动实体的轨迹追踪。这个监听器的内部方法体如下:

	/**
	 *  追踪开始 
	 */
	private void initOnStartTraceListener() {
		
		// 实例化开启轨迹服务回调接口
		startTraceListener = new OnStartTraceListener() {
			// 开启轨迹服务回调接口(arg0 : 消息编码,arg1 : 消息内容,详情查看类参考)
			@Override
			public void onTraceCallback(int arg0, String arg1) {
				Log.i("TAG", "onTraceCallback=" + arg1);
				if(arg0 == 0 || arg0 == 10006){
					startRefreshThread(true);
				}
			}

			// 轨迹服务推送接口(用于接收服务端推送消息,arg0 : 消息类型,arg1 : 消息内容,详情查看类参考)
			@Override
			public void onTracePushCallback(byte arg0, String arg1) {
				Log.i("TAG", "onTracePushCallback=" + arg1);
			}
		};
		
	}
在这个监听器的轨迹回调方法中,要调用刷新线程,实现不断的采集用户的位置点。

刷新线程的实现如下:

	/**
	 * 启动刷新线程
	 * @param isStart
	 */
	private void startRefreshThread(boolean isStart){
		
		if(refreshThread == null){
			refreshThread = new RefreshThread();
		}
		
		refreshThread.refresh = isStart;
		
		if(isStart){
			if(!refreshThread.isAlive()){
				refreshThread.start();
			}
		}
		else{
			refreshThread = null;
		}
		
	}
刷新线程的run方法如下:
	/**
	 * 轨迹刷新线程
	 * @author BLYang
	 */
	private class RefreshThread extends Thread{
		 
		protected boolean refresh = true;  
		
		public void run(){
			
			while(refresh){
				queryRealtimeTrack();
				try{
					Thread.sleep(packInterval * 1000);
				}catch(InterruptedException e){
					System.out.println("线程休眠失败");
				}
			}
			
		}
	}
	 
	/**
	 * 查询实时线路
	 */
	private void queryRealtimeTrack(){
		
		String entityName = this.entityName;
		String columnKey = "";
		int returnType = 0;
		int activeTime = 0;
		int pageSize = 10;
		int pageIndex = 1;
		
		this.client.queryEntityList(
				serviceId, 
				entityName, 
				columnKey, 
				returnType,
				activeTime, 
				pageSize, 
				pageIndex, 
				entityListener
				);
		
	}
	
在run方法中要调用查询实时线路的方法,不断的查询用户的当前位置点



在onCreate()方法的最后,启动轨迹追踪。

client.startTrace(trace, startTraceListener);  // 开启轨迹服务
在这个方法中调用startTraceListener,开启追踪服务。

这样就实现的轨迹追踪,但是只有这些方法并不能实时的显示追踪信息。

现在,再回去initOnEntityListener方法,在这个方法中要实现showRealtimeTrack()方法,这个方法就是用来实时展示的方法

	/**
	 * 展示实时线路图
	 * @param realtimeTrack
	 */
	protected void showRealtimeTrack(String realtimeTrack){
		
		if(refreshThread == null || !refreshThread.refresh){
			return;
		}
		
		//数据以JSON形式存取
		RealtimeTrackData realtimeTrackData = GsonService.parseJson(realtimeTrack, RealtimeTrackData.class);
		
		if(realtimeTrackData != null && realtimeTrackData.getStatus() ==0){
			
			LatLng latLng = realtimeTrackData.getRealtimePoint();
			
			if(latLng != null){
				pointList.add(latLng);
				drawRealtimePoint(latLng);
			}
			else{
				Toast.makeText(getApplicationContext(), "当前无轨迹点", Toast.LENGTH_LONG).show();
			}
			
		}
		
	}
	
	/**
	 * 画出实时线路点
	 * @param point
	 */
	private void drawRealtimePoint(LatLng point){
		
		baiduMap.clear();
		MapStatus mapStatus = new MapStatus.Builder().target(point).zoom(18).build();
		msUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
		realtimeBitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_gcoding);
		overlay = new MarkerOptions().position(point)
				.icon(realtimeBitmap).zIndex(9).draggable(true);
		
		if(pointList.size() >= 2  && pointList.size() <= 1000){
			polyline = new PolylineOptions().width(10).color(Color.RED).points(pointList);
		}
		
		addMarker();
		
	}
调用showRealtimeTrack方法,不断的将采集到的用户位置点增加到实体队列中,不断的重画出线路点,重画点需要调用drawRealtimePoint方法。

最后,在重画完成之后,将重画的点展示出来,调用addMarker方法,该方法的详细内容如下:

	private void addMarker(){
		
		if(msUpdate != null){
			baiduMap.setMapStatus(msUpdate);
		}
		
		if(polyline != null){
			baiduMap.addOverlay(polyline);
		}
		
		if(overlay != null){
			baiduMap.addOverlay(overlay);
		}
		
	}
不断的刷新地图的状态,刷新结束之后将坐标点图片和线路覆盖上去,形成整个界面。



第六步:最后一步,增加user-permission,提升系统的权限。

    <!-- 这个权限用于进行网络定位-->
	<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" />
    






  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值