專案結構
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 {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
}
protected abstract int getContentViewId();
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();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected 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;
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();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, TracingActivity.class);
startActivity(intent);
}
});
query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,TrackQueryActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
List<String> permissions = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isNeedRequestPermissions(permissions)) {
requestPermissions(permissions.toArray(new String[permissions.size()]), 0);
}
}
@Override
protected 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);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
if (trackApp.trackConf.contains("is_trace_started")
&& trackApp.trackConf.getBoolean("is_trace_started", true)) {
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;
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;
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;
@Override
protected 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<>();
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
double x = sensorEvent.values[SensorManager.DATA_X];
if (Math.abs(x - lastX) > 1.0) {
mCurrentDirection = (int) x;
if (!CommonUtil.isZeroPoint(CurrentLocation.latitude, CurrentLocation.longitude)) {
mapUtil.updateMapLocation(new LatLng(CurrentLocation.latitude, CurrentLocation.longitude), (float) mCurrentDirection);
}
}
lastX = x;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
@Override
public 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;
}
@Override
public 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();
}
@Override
protected 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() {
@Override
public 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() {
@Override
public void onReceiveLocation(TraceLocation location) {
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() {
@Override
public void onBindServiceCallback(int errorNo, String message) {
viewUtil.showToast(TracingActivity.this,
String.format("onBindServiceCallback, errorNo:%d, message:%s ", errorNo, message));
}
@Override
public 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));
}
@Override
public void onStopTraceCallback(int errorNo, String message) {
if (StatusCodes.SUCCESS == errorNo || StatusCodes.CACHE_TRACK_NOT_UPLOAD == errorNo) {
trackApp.isTraceStarted = false;
trackApp.isGatherStarted = false;
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));
}
@Override
public 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));
}
@Override
public 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));
}
@Override
public void onPushCallback(byte messageType, PushMessage pushMessage) {
}
};
}
static class RealTimeHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
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;
}
@Override
protected 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);
}
}
@Override
protected void onResume() {
super.onResume();
mapUtil.onResume();
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);
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();
}
}
}
}
@Override
protected void onPause() {
super.onPause();
mapUtil.onPause();
}
@Override
protected void onStop() {
super.onStop();
stopRealTimeLoc();
mSensorManager.unregisterListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
stopRealTimeLoc();
trackPoints.clear();
trackPoints = null;
mapUtil.clear();
}
@Override
protected 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;
@Override
protected 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() {
@Override
public 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() {
@Override
public 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();
}
@Override
protected 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 BaseActivity
implements 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;
@Override
protected 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();
}
@Override
protected 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);
}
@Override
public 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() {
@Override
public 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) {
}
}
@Override
public 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);
}
@Override
protected void onResume() {
super.onResume();
mapUtil.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapUtil.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (null != trackPoints) {
trackPoints.clear();
}
trackPoints = null;
mapUtil.clear();
}
@Override
protected 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 BaseActivity
implements 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;
@Override
protected 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() {
@Override
public 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() {
@Override
public 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();
}
@Override
public 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;
}
}
@Override
protected 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;
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;
public long serviceId = 162074;
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;
@Override
public 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() {
@Override
public 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;
}
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();
}
}
public void initRequest(BaseRequest request) {
request.setTag(getTag());
request.setServiceId(serviceId);
}
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" />
<application
android:name="siso.track.TrackApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android: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-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="bsewxQvoh47gxgzI7CIEb6VPCxZcIiTE" />
<activity
android:name="siso.track.activity.TracingActivity"
android:screenOrientation="portrait" />
<activity
android:name="siso.track.activity.TrackQueryActivity"
android:screenOrientation="portrait" />
<activity
android:name="siso.track.activity.TracingOptionsActivity"
android:screenOrientation="portrait"
android:theme="@style/AppBaseTheme" />
<activity
android:name="siso.track.activity.TrackQueryOptionsActivity"
android:screenOrientation="portrait"
android:theme="@style/AppBaseTheme" />
<service
android: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 26
buildToolsVersion "27.0.3"
defaultConfig {
applicationId 'siso.baidugj'
minSdkVersion 24
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles 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')
}
執行結果如圖: