757 lines
30 KiB
Java
757 lines
30 KiB
Java
package fr.chteufleur.mytrackingdog;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.SuppressLint;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.ActivityInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.graphics.Color;
|
|
import android.hardware.GeomagneticField;
|
|
import android.location.Location;
|
|
import android.location.LocationManager;
|
|
import android.net.Uri;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.os.Environment;
|
|
import android.os.Vibrator;
|
|
import android.preference.PreferenceManager;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.annotation.RequiresApi;
|
|
import android.support.v7.app.AppCompatActivity;
|
|
import android.support.v7.widget.Toolbar;
|
|
import android.util.Log;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.MotionEvent;
|
|
import android.view.Surface;
|
|
import android.view.View;
|
|
import android.view.WindowManager;
|
|
import android.widget.Button;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import org.jivesoftware.smack.SmackException;
|
|
import org.jivesoftware.smack.XMPPException;
|
|
import org.jxmpp.stringprep.XmppStringprepException;
|
|
import org.osmdroid.api.IMapController;
|
|
import org.osmdroid.config.Configuration;
|
|
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
|
import org.osmdroid.util.GeoPoint;
|
|
import org.osmdroid.views.MapView;
|
|
import org.osmdroid.views.overlay.Marker;
|
|
import org.osmdroid.views.overlay.Overlay;
|
|
import org.osmdroid.views.overlay.Polyline;
|
|
import org.osmdroid.views.overlay.compass.IOrientationConsumer;
|
|
import org.osmdroid.views.overlay.compass.IOrientationProvider;
|
|
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
|
import org.osmdroid.views.overlay.infowindow.BasicInfoWindow;
|
|
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
|
|
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Observable;
|
|
import java.util.Observer;
|
|
|
|
import fr.chteufleur.mytrackingdog.models.Notification;
|
|
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
|
import fr.chteufleur.mytrackingdog.models.beans.MyLocationArray;
|
|
import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation;
|
|
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
|
import fr.chteufleur.mytrackingdog.services.ServiceTrackingDog;
|
|
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
|
|
|
|
public class MainActivity extends AppCompatActivity implements IOrientationConsumer, Observer {
|
|
|
|
public static final String TAG = MainActivity.class.getName();
|
|
|
|
private static final int ACTIVITY_REQUEST_PICK_FILE = 1;
|
|
private static final int ACTIVITY_QR_CODE_GENERATOR = 2;
|
|
private static final int ACTIVITY_QR_CODE_READER = 3;
|
|
|
|
private ServiceTrackingDog serviceTrackingDog = null;
|
|
public static String appName = "";
|
|
|
|
private MyLocationNewOverlay mLocationOverlay;
|
|
private IOrientationProvider compass = null;
|
|
|
|
private Context ctx = null;
|
|
private MapView map = null;
|
|
|
|
private int deviceOrientation = 0;
|
|
private boolean zoomed = false;
|
|
|
|
private final int REQUEST_CODE_ASK_PERMISSION = 123;
|
|
|
|
private static final float LINE_WIDTH_BIG = 12;
|
|
|
|
private Button start_stop_trace;
|
|
private Button start_stop_dog_trace;
|
|
private Button add_object;
|
|
private TextView textViewCurrentLocation;
|
|
|
|
private MyLocation lastLocation = null;
|
|
private float distance = 0;
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.M)
|
|
protected void checkPermissions() {
|
|
int hasLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
|
|
int hasStoragePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
if (hasLocationPermission != PackageManager.PERMISSION_GRANTED || hasStoragePermission != PackageManager.PERMISSION_GRANTED) {
|
|
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ASK_PERMISSION);
|
|
}
|
|
}
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Activity life cycle">
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
appName = getString(R.string.app_name);
|
|
//handle permissions first, before map is created. not depicted here
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
checkPermissions();
|
|
}
|
|
|
|
//load/initialize the osmdroid configuration, this can be done
|
|
ctx = getApplicationContext();
|
|
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
|
|
setContentView(R.layout.main);
|
|
|
|
// Keep screen ON
|
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
|
setSupportActionBar(toolbar);
|
|
|
|
map = findViewById(R.id.map);
|
|
map.setTileSource(TileSourceFactory.OpenTopo);
|
|
|
|
// Add the ability to zoom with 2 fingers
|
|
map.setBuiltInZoomControls(false);
|
|
map.setMultiTouchControls(true);
|
|
map.setOnTouchListener(new View.OnTouchListener() {
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
@Override
|
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
map.onTouchEvent(motionEvent);
|
|
if (mLocationOverlay != null) {
|
|
mLocationOverlay.disableFollowLocation();
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
|
|
Button center_button = findViewById(R.id.center_button);
|
|
center_button.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View view) {
|
|
mLocationOverlay.enableFollowLocation();
|
|
}
|
|
});
|
|
|
|
// Center the map on a lat/lon
|
|
IMapController mapController = map.getController();
|
|
mapController.setZoom(11.0);
|
|
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
|
mapController.setCenter(startPoint);
|
|
|
|
// Current position on the map
|
|
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
|
map.getOverlays().add(this.mLocationOverlay);
|
|
mLocationOverlay.enableMyLocation();
|
|
mLocationOverlay.enableFollowLocation();
|
|
mLocationOverlay.setOptionsMenuEnabled(true);
|
|
|
|
|
|
start_stop_trace = findViewById(R.id.start_stop_trace);
|
|
start_stop_trace.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View view) {
|
|
changeStatusTrace();
|
|
}
|
|
});
|
|
start_stop_dog_trace = findViewById(R.id.start_stop_dog_trace);
|
|
start_stop_dog_trace.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View view) {
|
|
changeStatusDogTrace();
|
|
}
|
|
});
|
|
add_object = findViewById(R.id.add_object);
|
|
add_object.setVisibility(View.GONE);
|
|
add_object.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View view) {
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
WayPointLocation loc = serviceTrackingDog.addPointObjectTrail();
|
|
if (loc != null) {
|
|
GeoPoint gp = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
|
addMarker(gp, loc.isFound());
|
|
}
|
|
} else if (serviceTrackingDog.isDogActivated()) {
|
|
markAsFound();
|
|
}
|
|
}
|
|
});
|
|
|
|
textViewCurrentLocation = findViewById(R.id.textViewCurrentLocation);
|
|
textViewCurrentLocation.setVisibility(View.GONE);
|
|
|
|
if (serviceTrackingDog == null) {
|
|
serviceTrackingDog = new ServiceTrackingDog(
|
|
(Vibrator) getSystemService(Context.VIBRATOR_SERVICE),
|
|
PreferenceManager.getDefaultSharedPreferences(ctx),
|
|
getResources()
|
|
);
|
|
serviceTrackingDog.addObserver(this, ServiceGps.class.getName());
|
|
serviceTrackingDog.addObserver(this, ServiceXmpp.class.getName());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onResume(){
|
|
super.onResume();
|
|
|
|
//hack for x86
|
|
if (!"Android-x86".equalsIgnoreCase(Build.BRAND)) {
|
|
//lock the device in current screen orientation
|
|
int orientation;
|
|
int rotation = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
|
|
switch (rotation) {
|
|
case Surface.ROTATION_0:
|
|
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
|
this.deviceOrientation = 0;
|
|
break;
|
|
case Surface.ROTATION_90:
|
|
this.deviceOrientation = 90;
|
|
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
|
break;
|
|
case Surface.ROTATION_180:
|
|
this.deviceOrientation = 180;
|
|
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
|
break;
|
|
case Surface.ROTATION_270:
|
|
default:
|
|
this.deviceOrientation = 270;
|
|
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
|
break;
|
|
}
|
|
|
|
setRequestedOrientation(orientation);
|
|
}
|
|
|
|
serviceTrackingDog.setLocationManager((LocationManager) getSystemService(Context.LOCATION_SERVICE));
|
|
serviceTrackingDog.setAppName(appName);
|
|
serviceTrackingDog.startLocation();
|
|
|
|
mLocationOverlay.enableFollowLocation();
|
|
mLocationOverlay.enableMyLocation();
|
|
|
|
if (compass == null) {
|
|
compass = new InternalCompassOrientationProvider(this);
|
|
}
|
|
compass.startOrientationProvider(this);
|
|
|
|
if (map != null) {
|
|
map.onResume();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
pause();
|
|
}
|
|
|
|
private void pause() {
|
|
if (compass != null) {
|
|
compass.stopOrientationProvider();
|
|
compass.destroy();
|
|
compass = null;
|
|
}
|
|
if (mLocationOverlay != null) {
|
|
mLocationOverlay.disableFollowLocation();
|
|
mLocationOverlay.disableMyLocation();
|
|
}
|
|
if (map != null) {
|
|
map.onPause();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onBackPressed() {
|
|
if (serviceTrackingDog.isDogActivated() || serviceTrackingDog.isTraceurActivated()) {
|
|
Toast.makeText(ctx, "Une trace est en cours d'enregistrement.", Toast.LENGTH_LONG).show();
|
|
return ;
|
|
}
|
|
|
|
super.onBackPressed();
|
|
pause();
|
|
if (serviceTrackingDog != null) {
|
|
serviceTrackingDog.close();
|
|
}
|
|
zoomed = false;
|
|
}
|
|
//</editor-fold>
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Menu management">
|
|
@Override
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
// Inflate the menu; this adds items to the action bar if it is present.
|
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
|
|
|
MenuItem vibrationObjectMenuItem = menu.findItem(R.id.action_active_vibration_object);
|
|
vibrationObjectMenuItem.setChecked(serviceTrackingDog.isVibrationNearObjectEnabled());
|
|
|
|
MenuItem xmppObjectMenuItem = menu.findItem(R.id.action_active_xmpp);
|
|
xmppObjectMenuItem.setChecked(serviceTrackingDog.isXmppEnabled());
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
// Handle action bar item clicks here. The action bar will
|
|
// automatically handle clicks on the Home/Up button, so long
|
|
// as you specify a parent activity in AndroidManifest.xml.
|
|
int id = item.getItemId();
|
|
|
|
//noinspection SimplifiableIfStatement
|
|
if (id == R.id.action_import_gpx) {
|
|
Intent intent = new Intent(this, FilePicker.class);
|
|
intent.putExtra(FilePicker.EXTRA_FILE_PATH, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + appName);
|
|
startActivityForResult(intent, ACTIVITY_REQUEST_PICK_FILE);
|
|
return true;
|
|
|
|
} else if (id == R.id.action_qr_code_generator) {
|
|
Intent intent = new Intent(this, QRCodeGeneratorActivity.class);
|
|
startActivityForResult(intent, ACTIVITY_QR_CODE_GENERATOR);
|
|
|
|
} else if (id == R.id.action_qr_code_reader) {
|
|
Intent intent = new Intent(this, QRCodeReaderActivity.class);
|
|
startActivityForResult(intent, ACTIVITY_QR_CODE_READER);
|
|
|
|
} else if (id == R.id.action_send_gpx_trail) {
|
|
File trailFile = serviceTrackingDog.getLastExportedTrailFile();
|
|
if (trailFile != null) {
|
|
Intent shareIntent = new Intent();
|
|
shareIntent.setAction(Intent.ACTION_SEND);
|
|
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(trailFile));
|
|
shareIntent.setType("*/*");
|
|
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.action_send_to)));
|
|
} else {
|
|
Toast.makeText(ctx, "Aucune trace enregistré.", Toast.LENGTH_LONG).show();
|
|
}
|
|
return true;
|
|
|
|
} else if (id == R.id.action_active_vibration_object) {
|
|
boolean checked = item.isChecked();
|
|
item.setChecked(!checked);
|
|
serviceTrackingDog.setVibrationNearObjectEnabled(!checked);
|
|
return true;
|
|
|
|
} else if (id == R.id.action_active_xmpp) {
|
|
boolean checked = item.isChecked();
|
|
boolean newStat = !checked;
|
|
item.setChecked(newStat);
|
|
if (newStat) {
|
|
try {
|
|
serviceTrackingDog.enableXmpp();
|
|
Toast.makeText(ctx, "Connexion XMPP réussie", Toast.LENGTH_SHORT).show();
|
|
} catch (InterruptedException | IOException | SmackException | XMPPException e) {
|
|
e.printStackTrace();
|
|
Toast.makeText(ctx, "Echec de connexion XMPP", Toast.LENGTH_LONG).show();
|
|
item.setChecked(false);
|
|
serviceTrackingDog.disableXmpp();
|
|
}
|
|
} else {
|
|
serviceTrackingDog.disableXmpp();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
//</editor-fold>
|
|
|
|
@Override
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
if (resultCode == RESULT_OK) {
|
|
switch (requestCode) {
|
|
case ACTIVITY_REQUEST_PICK_FILE:
|
|
if (data.hasExtra(FilePicker.EXTRA_FILE_PATH)) {
|
|
serviceTrackingDog.importGpxTrace(new File(data.getStringExtra(FilePicker.EXTRA_FILE_PATH)));
|
|
updateDogTrace();
|
|
updateTrailTrace();
|
|
|
|
// Update distance
|
|
distance = serviceTrackingDog.calculTrailDistance();
|
|
if (distance != 0) {
|
|
updateDistance();
|
|
}
|
|
|
|
for (MyLocation loc: serviceTrackingDog.getListGeoPointObjectsTrail()) {
|
|
addMarker(new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()), false);
|
|
}
|
|
for (MyLocation loc: serviceTrackingDog.getListGeoPointObjectsDog()) {
|
|
boolean isFound = false;
|
|
if (loc instanceof WayPointLocation) {
|
|
isFound = ((WayPointLocation) loc).isFound();
|
|
}
|
|
addMarker(new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()), isFound);
|
|
}
|
|
if (!serviceTrackingDog.getListGeoPointTraceur().isEmpty()) {
|
|
updatePlaceholder(getTextTraceur());
|
|
} else if (!serviceTrackingDog.getListGeoPointDog().isEmpty()) {
|
|
updatePlaceholder(getTextDog());
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ACTIVITY_QR_CODE_READER:
|
|
if (data.hasExtra(QRCodeReaderActivity.EXTRA_SCANNED_TEXT)) {
|
|
String text = data.getStringExtra(QRCodeReaderActivity.EXTRA_SCANNED_TEXT);
|
|
try {
|
|
serviceTrackingDog.setOtherJid(text);
|
|
Log.i(TAG, "TEXT: "+text);
|
|
} catch (SmackException.NotConnectedException | InterruptedException | XmppStringprepException e) {
|
|
Log.e(TAG, "Fail send presence", e);
|
|
Toast.makeText(ctx, "Echec connexion avec le matériel", Toast.LENGTH_LONG).show();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
switch (requestCode) {
|
|
case REQUEST_CODE_ASK_PERMISSION:
|
|
Toast.makeText(ctx, "Permissions granted", Toast.LENGTH_LONG).show();
|
|
break;
|
|
|
|
default:
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onOrientationChanged(float orientationToMagneticNorth, IOrientationProvider source) {
|
|
//note, on devices without a compass this never fires...
|
|
MyLocation location = serviceTrackingDog.getCurrentLocation();
|
|
if (location == null) {
|
|
return ;
|
|
}
|
|
|
|
float gpsspeed = location.getSpeed();
|
|
float lat = (float) location.getLatitude();
|
|
float lon = (float) location.getLongitude();
|
|
float alt = (float) location.getAltitude();
|
|
long timeOfFix = location.getTime();
|
|
|
|
//only use the compass bit if we aren't moving, since gps is more accurate when we are moving
|
|
if (gpsspeed < 0.01) {
|
|
GeomagneticField gf = new GeomagneticField(lat, lon, alt, timeOfFix);
|
|
float trueNorth = orientationToMagneticNorth + gf.getDeclination();
|
|
if (trueNorth > 360.0f) {
|
|
trueNorth = trueNorth - 360.0f;
|
|
}
|
|
|
|
//this part adjusts the desired map rotation based on device orientation and compass heading
|
|
float t = (360 - trueNorth - this.deviceOrientation);
|
|
if (t < 0) {
|
|
t += 360;
|
|
}
|
|
if (t > 360) {
|
|
t -= 360;
|
|
}
|
|
//help smooth everything out
|
|
t = (int) t;
|
|
t = t / 5;
|
|
t = (int) t;
|
|
t = t * 5;
|
|
map.setMapOrientation(t);
|
|
}
|
|
}
|
|
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Map management">
|
|
private void changeStatusTrace() {
|
|
serviceTrackingDog.toggleTraceurActivation();
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
this.start_stop_trace.setText(R.string.trail_stop);
|
|
this.add_object.setVisibility(View.VISIBLE);
|
|
this.add_object.setText(R.string.trail_object);
|
|
this.start_stop_dog_trace.setVisibility(View.GONE);
|
|
updateDistance();
|
|
} else {
|
|
this.start_stop_trace.setText(R.string.trail_start);
|
|
this.add_object.setVisibility(View.GONE);
|
|
this.start_stop_dog_trace.setVisibility(View.VISIBLE);
|
|
}
|
|
}
|
|
|
|
private void changeStatusDogTrace() {
|
|
serviceTrackingDog.toggleDogActivation();
|
|
if (serviceTrackingDog.isDogActivated()) {
|
|
this.start_stop_dog_trace.setText(R.string.dog_stop);
|
|
this.add_object.setVisibility(View.VISIBLE);
|
|
this.add_object.setText(R.string.dog_object);
|
|
this.start_stop_trace.setVisibility(View.GONE);
|
|
this.textViewCurrentLocation.setVisibility(View.GONE);
|
|
updateDistance();
|
|
} else {
|
|
this.start_stop_dog_trace.setText(R.string.dog_start);
|
|
this.add_object.setVisibility(View.GONE);
|
|
this.start_stop_trace.setVisibility(View.VISIBLE);
|
|
}
|
|
}
|
|
|
|
private void addMarker(GeoPoint gp, boolean isFound) {
|
|
Marker marker = new Marker(map);
|
|
marker.setIcon(getResources().getDrawable(isFound ? R.drawable.ic_marker_blue : R.drawable.ic_marker_red));
|
|
marker.setPosition(gp);
|
|
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
|
marker.setTitle("Object");
|
|
marker.setDraggable(false);
|
|
marker.setOnMarkerClickListener(new Marker.OnMarkerClickListener() {
|
|
@Override
|
|
public boolean onMarkerClick(Marker marker, MapView mapView) {
|
|
if (serviceTrackingDog.isDogActivated()) {
|
|
GeoPoint gp = marker.getPosition();
|
|
WayPointLocation wpl = serviceTrackingDog.getPointTrail(gp.getLatitude(), gp.getLongitude());
|
|
if (wpl != null) {
|
|
wpl.setFound();
|
|
marker.setIcon(getResources().getDrawable(R.drawable.ic_marker_blue));
|
|
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
map.getOverlays().add(marker);
|
|
}
|
|
|
|
private void markAsFound() {
|
|
List<WayPointLocation> wpls = serviceTrackingDog.foundNearObjects();
|
|
boolean findMarker = false;
|
|
for (WayPointLocation wpl : wpls) {
|
|
if (wpl != null && !wpl.isFound()) {
|
|
wpl.setFound();
|
|
for (Overlay o : map.getOverlays()) {
|
|
if (o instanceof Marker) {
|
|
Marker marker = (Marker) o;
|
|
GeoPoint gp = marker.getPosition();
|
|
if (wpl.isEquals(gp.getLatitude(), gp.getLongitude())) {
|
|
marker.setIcon(getResources().getDrawable(R.drawable.ic_marker_blue));
|
|
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
serviceTrackingDog.addPointObjectDog();
|
|
findMarker = true;
|
|
break;
|
|
}
|
|
}
|
|
if (wpls.isEmpty() || !findMarker) {
|
|
// if no object is near -> add new found object
|
|
WayPointLocation wpl = serviceTrackingDog.addPointObjectDog();
|
|
GeoPoint gp = new GeoPoint(wpl.getLatitude(), wpl.getLongitude(), wpl.getAltitude());
|
|
addMarker(gp, true);
|
|
}
|
|
}
|
|
|
|
private void updateDogTrace() {
|
|
MyLocationArray listLoc = serviceTrackingDog.getListGeoPointDog();
|
|
if (listLoc.isEmpty()) {
|
|
return ;
|
|
}
|
|
|
|
Polyline line = new Polyline(map);
|
|
line.setTitle("Chien");
|
|
line.setSubDescription("Départ: "+listLoc.getFirstLocation().getDatePrint());
|
|
line.setColor(Color.BLUE);
|
|
line.setPoints(convertListLocation(listLoc));
|
|
line.setWidth(LINE_WIDTH_BIG);
|
|
line.setGeodesic(true);
|
|
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
|
map.getOverlayManager().add(line);
|
|
map.invalidate();
|
|
}
|
|
|
|
private void updateTrailTrace() {
|
|
MyLocationArray listLoc = serviceTrackingDog.getListGeoPointTraceur();
|
|
if (listLoc.isEmpty()) {
|
|
return ;
|
|
}
|
|
|
|
Polyline line = new Polyline(map);
|
|
line.setTitle("Traceur");
|
|
line.setSubDescription("Départ: "+listLoc.getFirstLocation().getDatePrint());
|
|
line.setColor(Color.RED);
|
|
line.setPoints(convertListLocation(listLoc));
|
|
line.setWidth(LINE_WIDTH_BIG);
|
|
line.setGeodesic(true);
|
|
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
|
map.getOverlayManager().add(line);
|
|
map.invalidate();
|
|
}
|
|
|
|
private List<GeoPoint> convertListLocation(MyLocationArray list) {
|
|
List<GeoPoint> ret = new ArrayList<>();
|
|
if (list != null) {
|
|
for (MyLocation loc : list) {
|
|
ret.add(new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
//</editor-fold>
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Service callback">
|
|
@Override
|
|
public void update(Observable observable, Object o) {
|
|
if (observable.getClass().getName().equals(ServiceGps.class.getName())) {
|
|
updateServiceGps((Notification) o);
|
|
} else if (observable.getClass().getName().equals(ServiceXmpp.class.getName())) {
|
|
updateServiceXmpp((Notification) o);
|
|
}
|
|
}
|
|
|
|
public void updateServiceGps(Notification notification) {
|
|
if (notification.isAction(ServiceGps.NOTIF_NEW_LOCATION)) {
|
|
Location loc = (Location) notification.getExtra(ServiceGps.NOTIF_NEW_LOCATION_VALUE_LOCATION);
|
|
if (loc != null) {
|
|
onNewLocation(new MyLocation(loc));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void updateServiceXmpp(Notification notification) {
|
|
if (notification.isAction(ServiceXmpp.NOTIF_NEW_LOCATION)) {
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
MyLocation loc = (MyLocation) notification.getExtra(ServiceXmpp.NOTIF_NEW_LOCATION_VALUE_LOCATION);
|
|
onNewLocation(loc);
|
|
}
|
|
} else if (notification.isAction(ServiceXmpp.NOTIF_NEW_OBJECT)) {
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
MyLocation locObj = (MyLocation) notification.getExtra(ServiceXmpp.NOTIF_NEW_OBJECT_VALUE_LOCATION);
|
|
GeoPoint gp = new GeoPoint(locObj.getLatitude(), locObj.getLongitude(), locObj.getAltitude());
|
|
addMarker(gp, false);
|
|
}
|
|
} else if (notification.isAction(ServiceXmpp.NOTIF_START_TRAIL)) {
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
changeStatusTrace();
|
|
}
|
|
});
|
|
} else if (notification.isAction(ServiceXmpp.NOTIF_STOP_TRAIL)) {
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
changeStatusTrace();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private MyLocation onNewLocation = null;
|
|
private void onNewLocation(MyLocation loc) {
|
|
if (loc != null) {
|
|
onNewLocation = loc;
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
GeoPoint currentPoint = new GeoPoint(onNewLocation.getLatitude(), onNewLocation.getLongitude(), onNewLocation.getAltitude());
|
|
if (mLocationOverlay.isFollowLocationEnabled()) {
|
|
map.getController().setCenter(currentPoint);
|
|
}
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
updateTrailTrace();
|
|
if (lastLocation != null) {
|
|
distance += onNewLocation.distanceTo(lastLocation);
|
|
updateDistance();
|
|
}
|
|
lastLocation = onNewLocation;
|
|
} else if (serviceTrackingDog.isDogActivated()) {
|
|
updateDogTrace();
|
|
if (lastLocation != null) {
|
|
distance += onNewLocation.distanceTo(lastLocation);
|
|
updateDistance();
|
|
}
|
|
lastLocation = onNewLocation;
|
|
}
|
|
|
|
float orientation = serviceTrackingDog.getOrientation(deviceOrientation);
|
|
if (orientation >= 0) {
|
|
map.setMapOrientation(orientation);
|
|
}
|
|
|
|
if (!zoomed) {
|
|
IMapController mapController = map.getController();
|
|
mapController.setZoom(19.0);
|
|
zoomed = true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
//</editor-fold>
|
|
|
|
//<editor-fold defaultstate="collapsed" desc="Placeholder management">
|
|
private void updateDistance() {
|
|
String text = null;
|
|
if (serviceTrackingDog.isTraceurActivated()) {
|
|
text = getTextTraceur();
|
|
} else if (serviceTrackingDog.isDogActivated()) {
|
|
text = getTextDog();
|
|
}
|
|
updatePlaceholder(text);
|
|
}
|
|
|
|
private String getTextTraceur() {
|
|
return String.format("Distance: %,dm\t\t\t\t\t\t\t\tObjets: %d", ((int) distance), serviceTrackingDog.getListGeoPointObjectsTrail().size());
|
|
}
|
|
|
|
private String getTextDog() {
|
|
String text = "";
|
|
MyLocation firstLoc = serviceTrackingDog.getListGeoPointDog().getFirstLocation();
|
|
MyLocation lastLoc = serviceTrackingDog.getListGeoPointDog().getLastLocation();
|
|
if (firstLoc != null) {
|
|
long time = lastLoc.getTime() - firstLoc.getTime();
|
|
time /= 1_000;
|
|
long s = (time % 60);
|
|
time /= 60;
|
|
long m = (time % 60);
|
|
time /= 60;
|
|
long h = (time % 60);
|
|
text = String.format("Time: %02d:%02d:%02d", h, m, s);
|
|
|
|
int nbFoundObject = 0;
|
|
for (MyLocation loc: serviceTrackingDog.getListGeoPointObjectsDog()) {
|
|
if (loc instanceof WayPointLocation && ((WayPointLocation) loc).isFound()) {
|
|
nbFoundObject++;
|
|
}
|
|
}
|
|
text += "\t\t\t\t\t\t\t\tObjets: "+nbFoundObject+"/"+serviceTrackingDog.getListGeoPointObjectsTrail().size();
|
|
}
|
|
return text;
|
|
}
|
|
|
|
private void updatePlaceholder(String text) {
|
|
if (text != null) {
|
|
this.textViewCurrentLocation.setText(text);
|
|
this.textViewCurrentLocation.setVisibility(View.VISIBLE);
|
|
}
|
|
}
|
|
//</editor-fold>
|
|
}
|