项目结构

BaseActivity.java

package siso.track.activity;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;import siso.track.R;public abstract class BaseActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(getContentViewId());}/*** 获取布局文件ID*/protected abstract int getContentViewId();/*** 设置Activity标题*/public void setTitle(int resId) {LinearLayout layout = (LinearLayout) findViewById(R.id.layout_top);TextView textView = (TextView) layout.findViewById(R.id.tv_activity_title);textView.setText(resId);}/*** 设置点击监听器*/public void setOnClickListener(View.OnClickListener listener) {LinearLayout layout = (LinearLayout) findViewById(R.id.layout_top);LinearLayout optionsButton = (LinearLayout) layout.findViewById(R.id.btn_activity_options);optionsButton.setOnClickListener(listener);}/*** 不显示设置按钮*/public void setOptionsButtonInVisible() {LinearLayout layout = (LinearLayout) findViewById(R.id.layout_top);LinearLayout optionsButton = (LinearLayout) layout.findViewById(R.id.btn_activity_options);optionsButton.setVisibility(View.INVISIBLE);}/*** 回退事件*/public void onBack(View v) {super.onBackPressed();}@Overrideprotected void onStart() {super.onStart();}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onPause() {super.onPause();}@Overrideprotected void onStop() {super.onStop();}@Overrideprotected void onRestart() {super.onRestart();}@Overrideprotected void onDestroy() {super.onDestroy();}}

MainActivity.java

package siso.track.activity;import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import com.baidu.mapapi.SDKInitializer;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.Trace;
import com.baidu.trace.api.entity.LocRequest;
import com.baidu.trace.api.entity.OnEntityListener;
import com.baidu.trace.model.OnTraceListener;
import com.baidu.trace.model.PushMessage;
import com.baidu.trace.model.TraceLocation;import siso.track.utils.BitmapUtil;
import siso.track.R;
import siso.track.TrackApplication;import java.util.ArrayList;
import java.util.List;public class MainActivity extends BaseActivity {private TrackApplication trackApp;private SDKReceiver mReceiver;/*** 构造广播监听类,监听 SDK key 验证以及网络异常广播*/public class SDKReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {String s = intent.getAction();if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) {Toast.makeText(MainActivity.this,"apikey验证失败,地图功能无法正常使用",Toast.LENGTH_SHORT).show();} else if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK)) {Toast.makeText(MainActivity.this,"apikey验证成功",Toast.LENGTH_SHORT).show();} else if (s.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) {Toast.makeText(MainActivity.this,"网络错误",Toast.LENGTH_SHORT).show();}}}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// apikey的授权需要一定的时间,在授权成功之前地图相关操作会出现异常;apikey授权成功后会发送广播通知,我们这里注册 SDK 广播监听者IntentFilter iFilter = new IntentFilter();iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_OK);iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);mReceiver = new SDKReceiver();registerReceiver(mReceiver, iFilter);init();siso.track.utils.BitmapUtil.init();}private void init() {trackApp = (TrackApplication) getApplicationContext();Button trace = (Button) findViewById(R.id.btn_trace);Button query = (Button) findViewById(R.id.btn_query);trace.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, TracingActivity.class);startActivity(intent);}});query.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this,TrackQueryActivity.class);startActivity(intent);}});}@Overrideprotected void onStart() {super.onStart();// 适配android M,检查权限List<String> permissions = new ArrayList<>();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isNeedRequestPermissions(permissions)) {requestPermissions(permissions.toArray(new String[permissions.size()]), 0);}}@Overrideprotected int getContentViewId() {return R.layout.activity_main;}private boolean isNeedRequestPermissions(List<String> permissions) {// 定位精确位置addPermission(permissions, Manifest.permission.ACCESS_FINE_LOCATION);// 存储权限addPermission(permissions, Manifest.permission.WRITE_EXTERNAL_STORAGE);// 读取手机状态addPermission(permissions, Manifest.permission.READ_PHONE_STATE);return permissions.size() > 0;}private void addPermission(List<String> permissionsList, String permission) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M&& checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {permissionsList.add(permission);}}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(mReceiver);if (trackApp.trackConf.contains("is_trace_started")&& trackApp.trackConf.getBoolean("is_trace_started", true)) {// 退出app停止轨迹服务时,不再接收回调,将OnTraceListener置空trackApp.mClient.setOnTraceListener(null);trackApp.mClient.stopTrace(trackApp.mTrace, null);trackApp.mClient.clear();} else {trackApp.mClient.clear();}trackApp.isTraceStarted = false;trackApp.isGatherStarted = false;SharedPreferences.Editor editor = trackApp.trackConf.edit();editor.remove("is_trace_started");editor.remove("is_gather_started");editor.apply();BitmapUtil.clear();}
}

TracingActivity.java

package siso.track.activity;import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SyncStatusObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;import com.baidu.mapapi.common.SysOSUtil;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.trace.api.entity.OnEntityListener;
import com.baidu.trace.api.track.HistoryTrackRequest;
import com.baidu.trace.api.track.HistoryTrackResponse;
import com.baidu.trace.api.track.LatestPoint;
import com.baidu.trace.api.track.LatestPointResponse;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.api.track.SupplementMode;
import com.baidu.trace.api.track.TrackPoint;
import com.baidu.trace.model.CoordType;
import com.baidu.trace.model.LocationMode;
import com.baidu.trace.model.OnTraceListener;
import com.baidu.trace.model.ProcessOption;
import com.baidu.trace.model.PushMessage;
import com.baidu.trace.model.SortType;
import com.baidu.trace.model.StatusCodes;
import com.baidu.trace.model.TraceLocation;
import com.baidu.trace.model.TransportMode;import siso.track.utils.CommonUtil;
import siso.track.utils.Constants;
import siso.track.utils.MapUtil;
import siso.track.utils.TrackReceiver;
import siso.track.utils.ViewUtil;
import siso.track.R;
import siso.track.TrackApplication;
import siso.track.model.CurrentLocation;import java.util.ArrayList;
import java.util.List;import siso.track.activity.BaseActivity;/*** 轨迹时时追踪* Created by zhh*/
public class TracingActivity extends BaseActivity implements View.OnClickListener, SensorEventListener {private TrackApplication trackApp = null;private ViewUtil viewUtil = null;private Button traceBtn = null;private Button gatherBtn = null;private PowerManager powerManager = null;private PowerManager.WakeLock wakeLock = null;private TrackReceiver trackReceiver = null;private SensorManager mSensorManager;private Double lastX = 0.0;private int mCurrentDirection = 0;/*** 地图工具*/private MapUtil mapUtil = null;/*** 轨迹服务监听器*/private OnTraceListener traceListener = null;/*** 轨迹监听器(用于接收纠偏后实时位置回调)*/private OnTrackListener trackListener = null;/*** Entity监听器(用于接收实时定位回调)*/private OnEntityListener entityListener = null;/*** 实时定位任务*/private RealTimeHandler realTimeHandler = new RealTimeHandler();private RealTimeLocRunnable realTimeLocRunnable = null;/*** 打包周期*/public int packInterval = Constants.DEFAULT_PACK_INTERVAL;/*** 轨迹点集合*/private List<LatLng> trackPoints;private boolean firstLocate = true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setTitle(R.string.tracing_title);setOptionsText();setOnClickListener(this);init();}public void setOptionsText() {LinearLayout layout = (LinearLayout) findViewById(R.id.layout_top);TextView textView = (TextView) layout.findViewById(R.id.tv_options);textView.setText("轨迹追踪设置");}private void init() {initListener();trackApp = (TrackApplication) getApplicationContext();viewUtil = new ViewUtil();mapUtil = MapUtil.getInstance();mapUtil.init((MapView) findViewById(R.id.tracing_mapView));mapUtil.setCenter(mCurrentDirection);//设置地图中心点powerManager = (PowerManager) trackApp.getSystemService(Context.POWER_SERVICE);mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);// 获取传感器管理服务traceBtn = (Button) findViewById(R.id.btn_trace);gatherBtn = (Button) findViewById(R.id.btn_gather);traceBtn.setOnClickListener(this);gatherBtn.setOnClickListener(this);setTraceBtnStyle();setGatherBtnStyle();trackPoints = new ArrayList<>();}@Overridepublic void onSensorChanged(SensorEvent sensorEvent) {//每次方向改变,重新给地图设置定位数据,用上一次的经纬度double x = sensorEvent.values[SensorManager.DATA_X];if (Math.abs(x - lastX) > 1.0) {// 方向改变大于1度才设置,以免地图上的箭头转动过于频繁mCurrentDirection = (int) x;if (!CommonUtil.isZeroPoint(CurrentLocation.latitude, CurrentLocation.longitude)) {mapUtil.updateMapLocation(new LatLng(CurrentLocation.latitude, CurrentLocation.longitude), (float) mCurrentDirection);}}lastX = x;}@Overridepublic void onAccuracyChanged(Sensor sensor, int i) {}@Overridepublic void onClick(View view) {switch (view.getId()) {// 追踪选项设置case R.id.btn_activity_options:ViewUtil.startActivityForResult(this, TracingOptionsActivity.class, Constants.REQUEST_CODE);break;case R.id.btn_trace:if (trackApp.isTraceStarted) {trackApp.mClient.stopTrace(trackApp.mTrace, traceListener);//停止服务} else {trackApp.mClient.startTrace(trackApp.mTrace, traceListener);//开始服务}break;case R.id.btn_gather:if (trackApp.isGatherStarted) {trackApp.mClient.stopGather(traceListener);} else {trackApp.mClient.setInterval(Constants.DEFAULT_GATHER_INTERVAL, packInterval);trackApp.mClient.startGather(traceListener);//开启采集}break;default:break;}}/*** 设置服务按钮样式*/private void setTraceBtnStyle() {boolean isTraceStarted = trackApp.trackConf.getBoolean("is_trace_started", false);if (isTraceStarted) {traceBtn.setText(R.string.stop_trace);traceBtn.setTextColor(ContextCompat.getColor(this, R.color.white));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {traceBtn.setBackground(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_sure, null));} else {traceBtn.setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_sure, null));}} else {traceBtn.setText(R.string.start_trace);traceBtn.setTextColor( ContextCompat.getColor(this, R.color.layout_title));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {traceBtn.setBackground(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_cancel, null));} else {traceBtn.setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_cancel, null));}}}/*** 设置采集按钮样式*/private void setGatherBtnStyle() {boolean isGatherStarted = trackApp.trackConf.getBoolean("is_gather_started", false);if (isGatherStarted) {gatherBtn.setText(R.string.stop_gather);gatherBtn.setTextColor(ContextCompat.getColor(this,R.color.white));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {gatherBtn.setBackground(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_sure, null));} else {gatherBtn.setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_sure, null));}} else {gatherBtn.setText(R.string.start_gather);gatherBtn.setTextColor(ContextCompat.getColor(this,R.color.layout_title));if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {gatherBtn.setBackground(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_cancel, null));} else {gatherBtn.setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(),R.mipmap.bg_btn_cancel, null));}}}/*** 实时定位任务*/class RealTimeLocRunnable implements Runnable {private int interval = 0;public RealTimeLocRunnable(int interval) {this.interval = interval;}@Overridepublic void run() {trackApp.getCurrentLocation(entityListener, trackListener);realTimeHandler.postDelayed(this, interval * 1000);}}public void startRealTimeLoc(int interval) {realTimeLocRunnable = new RealTimeLocRunnable(interval);realTimeHandler.post(realTimeLocRunnable);}public void stopRealTimeLoc() {if (null != realTimeHandler && null != realTimeLocRunnable) {realTimeHandler.removeCallbacks(realTimeLocRunnable);}trackApp.mClient.stopRealTimeLoc();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (null == data) {return;}if (data.hasExtra("locationMode")) {LocationMode locationMode = LocationMode.valueOf(data.getStringExtra("locationMode"));trackApp.mClient.setLocationMode(locationMode);//定位模式}trackApp.mTrace.setNeedObjectStorage(false);if (data.hasExtra("gatherInterval") && data.hasExtra("packInterval")) {int gatherInterval = data.getIntExtra("gatherInterval", Constants.DEFAULT_GATHER_INTERVAL);int packInterval = data.getIntExtra("packInterval", Constants.DEFAULT_PACK_INTERVAL);TracingActivity.this.packInterval = packInterval;trackApp.mClient.setInterval(gatherInterval, packInterval);//设置频率}}private void initListener() {trackListener = new OnTrackListener() {@Overridepublic void onLatestPointCallback(LatestPointResponse response) {//经过服务端纠偏后的最新的一个位置点,回调try {if (StatusCodes.SUCCESS != response.getStatus()) {return;}LatestPoint point = response.getLatestPoint();if (null == point || CommonUtil.isZeroPoint(point.getLocation().getLatitude(), point.getLocation().getLongitude())) {return;}LatLng currentLatLng = mapUtil.convertTrace2Map(point.getLocation());if (null == currentLatLng) {return;}if(firstLocate){firstLocate = false;Toast.makeText(TracingActivity.this,"起点获取中,请稍后...",Toast.LENGTH_SHORT).show();return;}//当前经纬度CurrentLocation.locTime = point.getLocTime();CurrentLocation.latitude = currentLatLng.latitude;CurrentLocation.longitude = currentLatLng.longitude;if (trackPoints == null) {return;}trackPoints.add(currentLatLng);mapUtil.drawHistoryTrack(trackPoints, false, mCurrentDirection);//时时动态的画出运动轨迹} catch (Exception x) {}}};entityListener = new OnEntityListener() {@Overridepublic void onReceiveLocation(TraceLocation location) {//本地LBSTraceClient客户端获取的位置try {if (StatusCodes.SUCCESS != location.getStatus() || CommonUtil.isZeroPoint(location.getLatitude(),location.getLongitude())) {return;}LatLng currentLatLng = mapUtil.convertTraceLocation2Map(location);if (null == currentLatLng) {return;}CurrentLocation.locTime = CommonUtil.toTimeStamp(location.getTime());CurrentLocation.latitude = currentLatLng.latitude;CurrentLocation.longitude = currentLatLng.longitude;if (null != mapUtil) {mapUtil.updateMapLocation(currentLatLng, mCurrentDirection);//显示当前位置mapUtil.animateMapStatus(currentLatLng);//缩放}} catch (Exception x) {}}};traceListener = new OnTraceListener() {@Overridepublic void onBindServiceCallback(int errorNo, String message) {viewUtil.showToast(TracingActivity.this,String.format("onBindServiceCallback, errorNo:%d, message:%s ", errorNo, message));}@Overridepublic void onStartTraceCallback(int errorNo, String message) {if (StatusCodes.SUCCESS == errorNo || StatusCodes.START_TRACE_NETWORK_CONNECT_FAILED <= errorNo) {trackApp.isTraceStarted = true;SharedPreferences.Editor editor = trackApp.trackConf.edit();editor.putBoolean("is_trace_started", true);editor.apply();setTraceBtnStyle();registerReceiver();}viewUtil.showToast(TracingActivity.this,String.format("onStartTraceCallback, errorNo:%d, message:%s ", errorNo, message));}@Overridepublic void onStopTraceCallback(int errorNo, String message) {if (StatusCodes.SUCCESS == errorNo || StatusCodes.CACHE_TRACK_NOT_UPLOAD == errorNo) {trackApp.isTraceStarted = false;trackApp.isGatherStarted = false;// 停止成功后,直接移除is_trace_started记录(便于区分用户没有停止服务,直接杀死进程的情况)SharedPreferences.Editor editor = trackApp.trackConf.edit();editor.remove("is_trace_started");editor.remove("is_gather_started");editor.apply();setTraceBtnStyle();setGatherBtnStyle();unregisterPowerReceiver();firstLocate = true;}viewUtil.showToast(TracingActivity.this,String.format("onStopTraceCallback, errorNo:%d, message:%s ", errorNo, message));}@Overridepublic void onStartGatherCallback(int errorNo, String message) {if (StatusCodes.SUCCESS == errorNo || StatusCodes.GATHER_STARTED == errorNo) {trackApp.isGatherStarted = true;SharedPreferences.Editor editor = trackApp.trackConf.edit();editor.putBoolean("is_gather_started", true);editor.apply();setGatherBtnStyle();stopRealTimeLoc();startRealTimeLoc(packInterval);}viewUtil.showToast(TracingActivity.this,String.format("onStartGatherCallback, errorNo:%d, message:%s ", errorNo, message));}@Overridepublic void onStopGatherCallback(int errorNo, String message) {if (StatusCodes.SUCCESS == errorNo || StatusCodes.GATHER_STOPPED == errorNo) {trackApp.isGatherStarted = false;SharedPreferences.Editor editor = trackApp.trackConf.edit();editor.remove("is_gather_started");editor.apply();setGatherBtnStyle();firstLocate = true;stopRealTimeLoc();startRealTimeLoc(Constants.LOC_INTERVAL);if (trackPoints.size() >= 1) {try {mapUtil.drawEndPoint(trackPoints.get(trackPoints.size() - 1));} catch (Exception e) {}}}viewUtil.showToast(TracingActivity.this,String.format("onStopGatherCallback, errorNo:%d, message:%s ", errorNo, message));}@Overridepublic void onPushCallback(byte messageType, PushMessage pushMessage) {}};}static class RealTimeHandler extends Handler {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);}}/*** 注册广播(电源锁、GPS状态)*/private void registerReceiver() {if (trackApp.isRegisterReceiver) {return;}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);trackApp.registerReceiver(trackReceiver, filter);trackApp.isRegisterReceiver = true;}private void unregisterPowerReceiver() {if (!trackApp.isRegisterReceiver) {return;}if (null != trackReceiver) {trackApp.unregisterReceiver(trackReceiver);}trackApp.isRegisterReceiver = false;}@Overrideprotected void onStart() {super.onStart();if (trackApp.trackConf.contains("is_trace_started")&& trackApp.trackConf.contains("is_gather_started")&& trackApp.trackConf.getBoolean("is_trace_started", false)&& trackApp.trackConf.getBoolean("is_gather_started", false)) {startRealTimeLoc(packInterval);} else {startRealTimeLoc(Constants.LOC_INTERVAL);}}@Overrideprotected void onResume() {super.onResume();mapUtil.onResume();mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);// 在Android 6.0及以上系统,若定制手机使用到doze模式,请求将应用添加到白名单。if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {String packageName = trackApp.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();}}}}@Overrideprotected void onPause() {super.onPause();mapUtil.onPause();}@Overrideprotected void onStop() {super.onStop();stopRealTimeLoc();mSensorManager.unregisterListener(this);}@Overrideprotected void onDestroy() {super.onDestroy();stopRealTimeLoc();trackPoints.clear();trackPoints = null;mapUtil.clear();}@Overrideprotected int getContentViewId() {return R.layout.activity_tracing;}}

TracingOptionsActivity.java

package siso.track.activity;import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;import com.baidu.trace.model.LocationMode;import siso.track.utils.Constants;
import siso.track.R;import static com.baidu.trace.model.LocationMode.High_Accuracy;/*** 轨迹追踪选项*/
public class TracingOptionsActivity extends BaseActivity {// 返回结果private Intent result = null;private EditText gatherIntervalText = null;private EditText packIntervalText = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setTitle(R.string.tracing_options_title);setOptionsButtonInVisible();init();}private void init() {gatherIntervalText = (EditText) findViewById(R.id.gather_interval);packIntervalText = (EditText) findViewById(R.id.pack_interval);gatherIntervalText.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View view, boolean hasFocus) {EditText textView = (EditText) view;String hintStr = textView.getHint().toString();if (hasFocus) {textView.setHint("");} else {textView.setHint(hintStr);}}});packIntervalText.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View view, boolean hasFocus) {EditText textView = (EditText) view;String hintStr = textView.getHint().toString();if (hasFocus) {textView.setHint("");} else {textView.setHint(hintStr);}}});}public void onCancel(View v) {super.onBackPressed();}public void onFinish(View v) {result = new Intent();RadioGroup locationModeGroup = (RadioGroup) findViewById(R.id.location_mode);RadioButton locationModeRadio = (RadioButton) findViewById(locationModeGroup.getCheckedRadioButtonId());LocationMode locationMode = High_Accuracy;//定位模式switch (locationModeRadio.getId()) {case R.id.device_sensors:locationMode = LocationMode.Device_Sensors;break;case R.id.battery_saving:locationMode = LocationMode.Battery_Saving;break;case R.id.high_accuracy:locationMode = High_Accuracy;break;default:break;}result.putExtra("locationMode", locationMode.name());EditText gatherIntervalText = (EditText) findViewById(R.id.gather_interval);EditText packIntervalText = (EditText) findViewById(R.id.pack_interval);String gatherIntervalStr = gatherIntervalText.getText().toString();String packIntervalStr = packIntervalText.getText().toString();if (!TextUtils.isEmpty(gatherIntervalStr)) {//采集频率try {result.putExtra("gatherInterval", Integer.parseInt(gatherIntervalStr));} catch (Exception ex) {ex.printStackTrace();}}if (!TextUtils.isEmpty(packIntervalStr)) {//打包频率try {result.putExtra("packInterval", Integer.parseInt(packIntervalStr));} catch (Exception ex) {ex.printStackTrace();}}setResult(Constants.RESULT_CODE, result);super.onBackPressed();}@Overrideprotected int getContentViewId() {return R.layout.activity_tracing_options;}}

TrackQueryActivity

package  siso.track.activity;import siso.track.TrackApplication;
import siso.track.activity.BaseActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.trace.api.track.DistanceRequest;
import com.baidu.trace.api.track.DistanceResponse;
import com.baidu.trace.api.track.HistoryTrackRequest;
import com.baidu.trace.api.track.HistoryTrackResponse;
import com.baidu.trace.api.track.LatestPointResponse;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.model.ProcessOption;
import com.baidu.trace.api.track.SupplementMode;
import com.baidu.trace.api.track.TrackPoint;
import com.baidu.trace.model.SortType;
import com.baidu.trace.model.StatusCodes;
import com.baidu.trace.model.TransportMode;
import com.baidu.trace.model.CoordType;import java.util.ArrayList;
import java.util.List;import siso.track.activity.BaseActivity;
import siso.track.utils.CommonUtil;
import siso.track.utils.Constants;
import siso.track.utils.MapUtil;
import siso.track.utils.ViewUtil;
import siso.track.R;/*** 轨迹查询*/
public class TrackQueryActivity extends BaseActivityimplements View.OnClickListener {private TrackApplication trackApp = null;private ViewUtil viewUtil = null;/*** 地图工具*/private MapUtil mapUtil = null;/*** 历史轨迹请求*/private HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest();/*** 轨迹监听器(用于接收历史轨迹回调)*/private OnTrackListener mTrackListener = null;/*** 查询轨迹的开始时间*/private long startTime = CommonUtil.getCurrentTime();/*** 查询轨迹的结束时间*/private long endTime = CommonUtil.getCurrentTime();/*** 轨迹点集合*/private List<LatLng> trackPoints = new ArrayList<>();/*** 轨迹排序规则*/private SortType sortType = SortType.asc;private int pageIndex = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setTitle(R.string.track_query_title);setOptionsText();setOnClickListener(this);trackApp = (TrackApplication) getApplicationContext();init();}public void setOptionsText() {LinearLayout layout = (LinearLayout) findViewById(R.id.layout_top);TextView textView = (TextView) layout.findViewById(R.id.tv_options);textView.setText("查询条件设置");}/*** 初始化*/private void init() {viewUtil = new ViewUtil();mapUtil = MapUtil.getInstance();mapUtil.init((MapView) findViewById(R.id.track_query_mapView));initListener();}/*** 轨迹查询设置回调** @param historyTrackRequestCode* @param resultCode* @param data*/@Overrideprotected void onActivityResult(int historyTrackRequestCode, int resultCode, Intent data) {if (null == data) {return;}trackPoints.clear();pageIndex = 1;if (data.hasExtra("startTime")) {startTime = data.getLongExtra("startTime", CommonUtil.getCurrentTime());}if (data.hasExtra("endTime")) {endTime = data.getLongExtra("endTime", CommonUtil.getCurrentTime());}ProcessOption processOption = new ProcessOption();if (data.hasExtra("radius")) {processOption.setRadiusThreshold(data.getIntExtra("radius", Constants.DEFAULT_RADIUS_THRESHOLD));}processOption.setTransportMode(TransportMode.walking);if (data.hasExtra("denoise")) {//去噪processOption.setNeedDenoise(data.getBooleanExtra("denoise", true));}if (data.hasExtra("vacuate")) {//抽稀processOption.setNeedVacuate(data.getBooleanExtra("vacuate", true));}if (data.hasExtra("mapmatch")) {//绑路processOption.setNeedMapMatch(data.getBooleanExtra("mapmatch", true));}historyTrackRequest.setProcessOption(processOption);if (data.hasExtra("processed")) {//纠偏historyTrackRequest.setProcessed(data.getBooleanExtra("processed", true));}queryHistoryTrack();}/*** 查询历史轨迹*/private void queryHistoryTrack() {trackApp.initRequest(historyTrackRequest);historyTrackRequest.setSupplementMode(SupplementMode.no_supplement);historyTrackRequest.setSortType(SortType.asc);historyTrackRequest.setCoordTypeOutput(CoordType.bd09ll);historyTrackRequest.setEntityName(trackApp.entityName);historyTrackRequest.setStartTime(startTime);historyTrackRequest.setEndTime(endTime);historyTrackRequest.setPageIndex(pageIndex);historyTrackRequest.setPageSize(Constants.PAGE_SIZE);trackApp.mClient.queryHistoryTrack(historyTrackRequest, mTrackListener);}/*** 按钮点击事件** @param view*/@Overridepublic void onClick(View view) {switch (view.getId()) {// 轨迹查询选项case R.id.btn_activity_options:ViewUtil.startActivityForResult(this, TrackQueryOptionsActivity.class, Constants.REQUEST_CODE);break;default:break;}}private void initListener() {mTrackListener = new OnTrackListener() {@Overridepublic void onHistoryTrackCallback(HistoryTrackResponse response) {try {int total = response.getTotal();if (StatusCodes.SUCCESS != response.getStatus()) {viewUtil.showToast(TrackQueryActivity.this, response.getMessage());} else if (0 == total) {viewUtil.showToast(TrackQueryActivity.this, getString(R.string.no_track_data));} else {List<TrackPoint> points = response.getTrackPoints();if (null != points) {for (TrackPoint trackPoint : points) {if (!CommonUtil.isZeroPoint(trackPoint.getLocation().getLatitude(),trackPoint.getLocation().getLongitude())) {trackPoints.add(MapUtil.convertTrace2Map(trackPoint.getLocation()));}}}}//查找下一页数据if (total > Constants.PAGE_SIZE * pageIndex) {historyTrackRequest.setPageIndex(++pageIndex);queryHistoryTrack();} else {mapUtil.drawHistoryTrack(trackPoints, true, 0);//画轨迹}queryDistance();// 查询里程} catch (Exception e) {}}@Overridepublic void onDistanceCallback(DistanceResponse response) {viewUtil.showToast(TrackQueryActivity.this, "里程:" + response.getDistance());super.onDistanceCallback(response);}};}private void queryDistance() {DistanceRequest distanceRequest = new DistanceRequest(trackApp.getTag(), trackApp.serviceId, trackApp.entityName);distanceRequest.setStartTime(startTime);// 设置开始时间distanceRequest.setEndTime(endTime);// 设置结束时间distanceRequest.setProcessed(true);// 纠偏ProcessOption processOption = new ProcessOption();// 创建纠偏选项实例processOption.setNeedDenoise(true);// 去噪processOption.setNeedMapMatch(true);// 绑路processOption.setTransportMode(TransportMode.walking);// 交通方式为步行distanceRequest.setProcessOption(processOption);// 设置纠偏选项distanceRequest.setSupplementMode(SupplementMode.no_supplement);// 里程填充方式为无trackApp.mClient.queryDistance(distanceRequest, mTrackListener);// 查询里程}@Overrideprotected void onResume() {super.onResume();mapUtil.onResume();}@Overrideprotected void onPause() {super.onPause();mapUtil.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();if (null != trackPoints) {trackPoints.clear();}trackPoints = null;mapUtil.clear();}@Overrideprotected int getContentViewId() {return R.layout.activity_trackquery;}
}

TrackQueryOptionsActivity.java

package siso.track.activity;import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;import siso.track.TrackApplication;
import siso.track.utils.CommonUtil;
import siso.track.utils.Constants;
import siso.track.utils.DateDialog;import java.text.SimpleDateFormat;import siso.track.activity.BaseActivity;
import siso.track.R;/*** 轨迹查询选项*/
public class TrackQueryOptionsActivity extends BaseActivityimplements CompoundButton.OnCheckedChangeListener {private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");private TrackApplication trackApp = null;private Intent result = null;private DateDialog dateDialog = null;private Button startTimeBtn = null;private Button endTimeBtn = null;private CheckBox processedCBx = null;private CheckBox denoiseCBx = null;private CheckBox vacuateCBx = null;private CheckBox mapmatchCBx = null;private TextView radiusText = null;private DateDialog.Callback startTimeCallback = null;private DateDialog.Callback endTimeCallback = null;private long startTime = CommonUtil.getCurrentTime();private long endTime = CommonUtil.getCurrentTime();private boolean isProcessed = true;private boolean isDenoise = false;private boolean isVacuate = false;private boolean isMapmatch = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setTitle(R.string.track_query_options_title);setOptionsButtonInVisible();init();trackApp = (TrackApplication) getApplication();}private void init() {result = new Intent();startTimeBtn = (Button) findViewById(R.id.start_time);endTimeBtn = (Button) findViewById(R.id.end_time);processedCBx = (CheckBox) findViewById(R.id.processed);denoiseCBx = (CheckBox) findViewById(R.id.denoise);vacuateCBx = (CheckBox) findViewById(R.id.vacuate);mapmatchCBx = (CheckBox) findViewById(R.id.mapmatch);radiusText = (TextView) findViewById(R.id.radius_threshold);StringBuilder startTimeBuilder = new StringBuilder();startTimeBuilder.append(getResources().getString(R.string.start_time));startTimeBuilder.append(simpleDateFormat.format(System.currentTimeMillis()));startTimeBtn.setText(startTimeBuilder.toString());StringBuilder endTimeBuilder = new StringBuilder();endTimeBuilder.append(getResources().getString(R.string.end_time));endTimeBuilder.append(simpleDateFormat.format(System.currentTimeMillis()));endTimeBtn.setText(endTimeBuilder.toString());processedCBx.setOnCheckedChangeListener(this);denoiseCBx.setOnCheckedChangeListener(this);vacuateCBx.setOnCheckedChangeListener(this);mapmatchCBx.setOnCheckedChangeListener(this);}public void onStartTime(View v) {if (null == startTimeCallback) {startTimeCallback = new DateDialog.Callback() {@Overridepublic void onDateCallback(long timeStamp) {TrackQueryOptionsActivity.this.startTime = timeStamp;StringBuilder startTimeBuilder = new StringBuilder();startTimeBuilder.append(getResources().getString(R.string.start_time));startTimeBuilder.append(simpleDateFormat.format(timeStamp * 1000));startTimeBtn.setText(startTimeBuilder.toString());}};}if (null == dateDialog) {dateDialog = new DateDialog(this, startTimeCallback);} else {dateDialog.setCallback(startTimeCallback);}dateDialog.show();}public void onEndTime(View v) {if (null == endTimeCallback) {endTimeCallback = new DateDialog.Callback() {@Overridepublic void onDateCallback(long timeStamp) {TrackQueryOptionsActivity.this.endTime = timeStamp;StringBuilder endTimeBuilder = new StringBuilder();endTimeBuilder.append(getResources().getString(R.string.end_time));endTimeBuilder.append(simpleDateFormat.format(timeStamp * 1000));endTimeBtn.setText(endTimeBuilder.toString());}};}if (null == dateDialog) {dateDialog = new DateDialog(this, endTimeCallback);} else {dateDialog.setCallback(endTimeCallback);}dateDialog.show();}public void onCancel(View v) {super.onBackPressed();}public void onFinish(View v) {result.putExtra("startTime", startTime);result.putExtra("endTime", endTime);result.putExtra("processed", isProcessed);result.putExtra("denoise", isDenoise);result.putExtra("vacuate", isVacuate);result.putExtra("mapmatch", isMapmatch);String radiusStr = radiusText.getText().toString();if (!TextUtils.isEmpty(radiusStr)) {try {result.putExtra("radius", Integer.parseInt(radiusStr));} catch (Exception ex) {ex.printStackTrace();}}setResult(Constants.RESULT_CODE, result);super.onBackPressed();}@Overridepublic void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {switch (compoundButton.getId()) {case R.id.processed:isProcessed = isChecked;break;case R.id.denoise:isDenoise = isChecked;break;case R.id.vacuate:isVacuate = isChecked;break;case R.id.mapmatch:isMapmatch = isChecked;break;default:break;}}@Overrideprotected int getContentViewId() {return R.layout.activity_trackquery_options;}}

TrackApplication.java

package siso.track;import android.app.Application;
import android.app.Notification;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.DisplayMetrics;import com.baidu.mapapi.SDKInitializer;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.Trace;
import com.baidu.trace.api.entity.LocRequest;
import com.baidu.trace.api.entity.OnEntityListener;
import com.baidu.trace.api.track.LatestPointRequest;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.model.BaseRequest;
import com.baidu.trace.model.OnCustomAttributeListener;
import com.baidu.trace.model.ProcessOption;
import com.baidu.trace.model.TransportMode;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;/*** Created by zhh*/public class TrackApplication extends Application {private AtomicInteger mSequenceGenerator = new AtomicInteger();private LocRequest locRequest = null;public Context mContext = null;public SharedPreferences trackConf = null;/*** 轨迹客户端*/public LBSTraceClient mClient = null;/*** 轨迹服务*/public Trace mTrace = null;/*** 轨迹服务ID*/public long serviceId = 162074;//这里是申请的鹰眼服务id/*** Entity标识*/public String entityName = "myTrace";public boolean isRegisterReceiver = false;/*** 服务是否开启标识*/public boolean isTraceStarted = false;/*** 采集是否开启标识*/public boolean isGatherStarted = false;public static int screenWidth = 0;public static int screenHeight = 0;@Overridepublic void onCreate() {super.onCreate();mContext = getApplicationContext();entityName = siso.track.utils.CommonUtil.getImei(this);// 若为创建独立进程,则不初始化成员变量if ("siso.track:remote".equals(siso.track.utils.CommonUtil.getCurProcessName(mContext))) {return;}SDKInitializer.initialize(mContext);getScreenSize();mClient = new LBSTraceClient(mContext);mTrace = new Trace(serviceId, entityName);trackConf = getSharedPreferences("track_conf", MODE_PRIVATE);locRequest = new LocRequest(serviceId);mClient.setOnCustomAttributeListener(new OnCustomAttributeListener() {@Overridepublic Map<String, String> onTrackAttributeCallback() {Map<String, String> map = new HashMap<>();map.put("key1", "value1");map.put("key2", "value2");return map;}});clearTraceStatus();}/*** 获取当前位置*/public void getCurrentLocation(OnEntityListener entityListener, OnTrackListener trackListener) {// 网络连接正常,开启服务及采集,则查询纠偏后实时位置;否则进行实时定位if (siso.track.utils.NetUtil.isNetworkAvailable(mContext)&& trackConf.contains("is_trace_started")&& trackConf.contains("is_gather_started")&& trackConf.getBoolean("is_trace_started", false)&& trackConf.getBoolean("is_gather_started", false)) {LatestPointRequest request = new LatestPointRequest(getTag(), serviceId, entityName);ProcessOption processOption = new ProcessOption();processOption.setRadiusThreshold(50);processOption.setTransportMode(TransportMode.walking);processOption.setNeedDenoise(true);processOption.setNeedMapMatch(true);request.setProcessOption(processOption);mClient.queryLatestPoint(request, trackListener);} else {mClient.queryRealTimeLoc(locRequest, entityListener);}}/*** 获取屏幕尺寸*/private void getScreenSize() {DisplayMetrics dm = getResources().getDisplayMetrics();screenHeight = dm.heightPixels;screenWidth = dm.widthPixels;}/*** 清除Trace状态:初始化app时,判断上次是正常停止服务还是强制杀死进程,根据trackConf中是否有is_trace_started字段进行判断。** 停止服务成功后,会将该字段清除;若未清除,表明为非正常停止服务。*/private void clearTraceStatus() {if (trackConf.contains("is_trace_started") || trackConf.contains("is_gather_started")) {SharedPreferences.Editor editor = trackConf.edit();editor.remove("is_trace_started");editor.remove("is_gather_started");editor.apply();}}/*** 初始化请求公共参数** @param request*/public void initRequest(BaseRequest request) {request.setTag(getTag());request.setServiceId(serviceId);}/*** 获取请求标识** @return*/public int getTag() {return mSequenceGenerator.incrementAndGet();}}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="siso.track"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_OWNER_DATA" /><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" /><applicationandroid:name="siso.track.TrackApplication"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activityandroid:name="siso.track.activity.MainActivity"android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><meta-dataandroid:name="com.baidu.lbsapi.API_KEY"android:value="bsewxQvoh47gxgzI7CIEb6VPCxZcIiTE" /><activityandroid:name="siso.track.activity.TracingActivity"android:screenOrientation="portrait" /><activityandroid:name="siso.track.activity.TrackQueryActivity"android:screenOrientation="portrait" /><activityandroid:name="siso.track.activity.TracingOptionsActivity"android:screenOrientation="portrait"android:theme="@style/AppBaseTheme" /><activityandroid:name="siso.track.activity.TrackQueryOptionsActivity"android:screenOrientation="portrait"android:theme="@style/AppBaseTheme" /><serviceandroid:name="com.baidu.trace.LBSTraceService"android:enabled="true"android:exported="true"android:process=":remote" /></application></manifest>

build.gradle

apply plugin: 'com.android.application'android {compileSdkVersion 26buildToolsVersion "27.0.3"defaultConfig {applicationId 'siso.baidugj'minSdkVersion 24targetSdkVersion 24versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}sourceSets {main {jniLibs.srcDirs = ['libs']}}productFlavors {}
}dependencies {compile fileTree(include: ['*.jar'], dir: 'libs')testCompile 'junit:junit:4.12'compile 'com.android.support:appcompat-v7:26.1.0'compile files('libs/BaiduLBS_Android.jar')compile files('libs/BaiduTraceSDK_v3_0_4.jar')compile files('libs/bos-android-sdk-1.0.2.jar')
}

运行结果如图:

百度地图轨迹(Andriod SDK)相关推荐

  1. 百度地图轨迹回放,自定义路书,边走边画线

    转自:https://www.cnblogs.com/syj2016/p/5685294.html 百度地图轨迹回放,自定义路书,边走边画线 在原有的百度路书的基础上,做了修改,使其能实现边走边画线的 ...

  2. 利用百度地图Android定位SDK获取经纬度

    环境的搭建(参考上一次的文章) 百度地图Android定位SDK的使用 2.在Android studio里设计程序来获取经纬度 界面布局activity_main.xml文件的源代码: <?x ...

  3. 百度地图AR识别SDK免费推出

    在今年的9月份,百度地图开放平台曾做过一期关于<LBS+AI新浪潮,不止于此>的主题沙龙,现场开发者反响爆棚,也一起探索了在AI技术的加持下,地图产品及依赖于位置服务相关的开发者产品将有哪 ...

  4. Android 集成百度地图AR识别SDK(二)

    废话 今天我们开始集成百度地图AR识别SDK(后面简称AR SDK)的第二章,这一章我们主要讲Android Studio如何配置AR SDK 我们如果单单只看文档的话,很难看懂如何集成,我们需要结合 ...

  5. Android 集成百度地图AR识别SDK(一)

    废话 我最近一直在想手机上如何实现AR功能,很多方法都试过了,但是要不是一些官方文档看不懂,要不就是集成起来特别麻烦,总之就是无从下手 有一天,一位同事突然和我说百度地图有AR功能,于是我赶紧试了下, ...

  6. android百度地图轨迹实现,android 获取GPS经纬度在百度地图上绘制轨迹

    实现将一组GPS模块获取的经纬度数据在百度地图上绘制轨迹 1.将经纬度转换成百度地图坐标 /** * 标准的GPS经纬度坐标直接在地图上绘制会有偏移,这是测绘局和地图商设置的加密,要转换成百度地图坐标 ...

  7. 百度地图轨迹开发,如何绘制带有箭头的折线

    最近在开发百度地图时,需要绘制行人行走的轨迹,并在轨迹内使用箭头表示方向,和我们平常使用百度地图导航时一样,能通过箭头表示人行走的方向.        通过百度地图API,我们很容易能找到划线的方法P ...

  8. 百度地图API Android SDK 常见问题

    http://developer.baidu.com/map/sdkandev-question.htm#col32 常见问题 1 使用须知 2 百度用户和Key 2.1 如何注册百度用户? 2.2 ...

  9. vue项目中 使用百度地图 轨迹动画

    在上篇博客中,介绍了如何在vue项目中集成百度地图,这篇博客主要是说如何在vue项目中使用轨迹动画 在项目开发过程中,比如你需要实时的观察一个人的行走路线,行走过程.  这个时候我们就需要在地图上使用 ...

最新文章

  1. 五连阳回调买入法_“4连阳+1阴”这种股票,吃透主升浪!挣得万贯家财
  2. python 遍历文件夹 提取文件内信息 存为新文件名_python获取遍历文件名称并分别保存为XLSX和CSV格式...
  3. opencv中Mat矩阵的合并与拼接
  4. 深度学习(神经网络)[1]——单层感知器
  5. python的函数结构_Python学习(四)常见函数及控制结构
  6. 【逐帧分析】《黑神话:悟空》gameplay相关的技术和调整细节整理
  7. 学成在线--13.RabbitMQ工作模式
  8. 第九章 利用化学知识制药
  9. 第一次冲刺阶段(五)
  10. SpringBoot(十四)_springboot使用内置定时任务Scheduled的使用(一)
  11. VLOOKUP函数返回错误值#N/A的两种解决方法
  12. VMware 虚拟机图文安装和配置 AlmaLinux OS 8.6 教程
  13. Linux文字识别软件,linux下的文字识别软件tesseract ( OCR software in Linux: tesseract )
  14. ic 卡获取帐号apdu指令_APDU命令
  15. 屌丝变身海归精英?揭秘芝麻信用分黑色产业链
  16. 乌云沙龙:赛棍的自我修养
  17. tf10: 谷歌Deep Dream
  18. EasyBoot制作启动光盘教程
  19. 学会使用这些常见的网络诊断工具,助力你的网络编程之路
  20. 苏嵌实训——day7

热门文章

  1. JAVA计算斐波那契第100万项的最快算法排名汇总
  2. 微信小程序获取手机号(Java)
  3. php怎么调节字体大小,ps中怎么调整字体大小
  4. GTX1080 matlab计算,GTX 1080显卡计算性能测试:专业的归专业,游戏的归游戏
  5. 计算机毕业设计 SSM税务信息管理系统 缴税信息管理系统 税务申报管理系统
  6. 腾讯云 宝塔linux建站
  7. FPGA Verilog实现二进制转BCD码
  8. 【iOS开发】—— KVC
  9. java命令, 指定jdk启动方法
  10. 【JAVA 】看漫画学java