diff --git a/OsmAnd-java/src/net/osmand/util/Algorithms.java b/OsmAnd-java/src/net/osmand/util/Algorithms.java
index 7469863406..2c94bf125d 100644
--- a/OsmAnd-java/src/net/osmand/util/Algorithms.java
+++ b/OsmAnd-java/src/net/osmand/util/Algorithms.java
@@ -100,6 +100,31 @@ public class Algorithms {
}
}
+
+ /**
+ * Parse the color string, and return the corresponding color-int.
+ * If the string cannot be parsed, throws an IllegalArgumentException
+ * exception. Supported formats are:
+ * #RRGGBB
+ * #AARRGGBB
+ * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
+ * 'yellow', 'lightgray', 'darkgray'
+ */
+ public static int parseColor(String colorString) {
+ if (colorString.charAt(0) == '#') {
+ // Use a long to avoid rollovers on #ffXXXXXX
+ long color = Long.parseLong(colorString.substring(1), 16);
+ if (colorString.length() == 7) {
+ // Set the alpha value
+ color |= 0x00000000ff000000;
+ } else if (colorString.length() != 9) {
+ throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
+ }
+ return (int)color;
+ }
+ throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
+ }
+
public static int extractFirstIntegerNumber(String s) {
int i = 0;
for (int k = 0; k < s.length(); k++) {
diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 5542c05a8d..f04c1be14f 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -1546,7 +1546,7 @@
Прерывание музыки во время объявления
Прерывание музыки
Поделиться маршрутом используя файл GPX
- Уникальный ID устройства
+ Ключ доступа
Настройка параметров мониторинга и установка персонального канала мониторинга
OpenStreetMap-Monitoring - продвинутый живой мониторинг с множеством средств удалённого контроля http://osmo.mobi
OsMo (Продвинутый онлайн-мониторинг)
@@ -1661,5 +1661,5 @@ OsmAnd - открытый источник и активно развается.
голубой
синий
маджента
-
+ зелёный
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index e64efc4b02..153633ae05 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -9,6 +9,10 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
+ User %1$s joined group %2$s
+ User %1$s left group %2$s
+ Show group notifications
+ Show toast messages when user joins or leavs the group
Follow
Sign in
In order to create groups you need to be a registered user of OsMo.
diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
index afc859fa90..0089b68116 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
@@ -834,6 +834,8 @@ public class OsmandSettings {
public final OsmandPreference OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal();
+ public final OsmandPreference OSMO_SHOW_GROUP_NOTIFICATIONS = new BooleanPreference("osmo_show_toast_notifications", true).makeGlobal();
+
public final CommonPreference OSMO_SAVE_TRACK_INTERVAL = new IntPreference("osmo_save_track_interval", 5000).makeGlobal().cache();
public final OsmandPreference OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal();
diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java b/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java
index 0563a47902..94b89a9d50 100644
--- a/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java
+++ b/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java
@@ -44,7 +44,7 @@ public class DownloadFileHelper {
return e != null && e.getMessage().equals("Interrupted");
}
- private InputStream getInputStreamToDownload(final URL url, final boolean forceWifi) throws IOException {
+ public InputStream getInputStreamToDownload(final URL url, final boolean forceWifi) throws IOException {
InputStream cis = new InputStream() {
byte[] buffer = new byte[BUFFER_SIZE];
int bufLen = 0;
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoControlDevice.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoControlDevice.java
index bae8a5a135..3554fcdff1 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoControlDevice.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoControlDevice.java
@@ -23,9 +23,12 @@ public class OsMoControlDevice implements OsMoReactor {
private OsMoService service;
private OsmandApplication app;
private OsMoTracker tracker;
+ private OsMoPlugin plugin;
- public OsMoControlDevice(OsmandApplication app, OsMoService service, OsMoTracker tracker) {
+ public OsMoControlDevice(OsmandApplication app, OsMoPlugin plugin,
+ OsMoService service, OsMoTracker tracker) {
this.app = app;
+ this.plugin = plugin;
this.service = service;
this.tracker = tracker;
service.registerReactor(this);
@@ -96,6 +99,8 @@ public class OsMoControlDevice implements OsMoReactor {
}
}
return true;
+ } else if(command.equals("TP")) {
+ plugin.getDownloadGpxTask(true).execute(obj);
}
return false;
}
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
index e725f4a111..3c4acb4613 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
@@ -7,7 +7,10 @@ import java.util.List;
import java.util.Map;
import net.osmand.Location;
+import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
+import net.osmand.plus.GPXUtilities.GPXFile;
+import net.osmand.plus.R;
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoGroup;
import net.osmand.plus.osmo.OsMoTracker.OsmoTrackerListener;
@@ -16,6 +19,8 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import android.os.AsyncTask;
+
public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
private static final String GROUP_NAME = "name";
@@ -29,11 +34,14 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
private static final String DELETED = "deleted";
private static final String GROUP_TRACKER_ID = "group_tracker_id";
private static final String LAST_ONLINE = "last_online";
+ private static final String TRACK = "track";
private OsMoTracker tracker;
private OsMoService service;
private OsMoGroupsStorage storage;
private OsMoGroupsUIListener uiListener;
+ private OsMoPlugin plugin;
+ private OsmandApplication app;
public interface OsMoGroupsUIListener {
@@ -42,12 +50,14 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
public void deviceLocationChanged(OsMoDevice device);
}
- public OsMoGroups(OsMoService service, OsMoTracker tracker, OsmandSettings settings) {
+ public OsMoGroups(OsMoPlugin plugin, OsMoService service, OsMoTracker tracker, OsmandApplication app) {
+ this.plugin = plugin;
this.service = service;
this.tracker = tracker;
+ this.app = app;
service.registerReactor(this);
tracker.setTrackerListener(this);
- storage = new OsMoGroupsStorage(this, settings.OSMO_GROUPS);
+ storage = new OsMoGroupsStorage(this, app.getSettings().OSMO_GROUPS);
storage.load();
}
@@ -152,13 +162,23 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
group = storage.getGroup(gid);
if(group != null) {
List delta = mergeGroup(group, obj, false);
+ StringBuilder b = new StringBuilder();
for(OsMoDevice d : delta) {
if(d.getDeletedTimestamp() != 0 && d.isEnabled()) {
+ if(group.name != null) {
+ b.append(app.getString(R.string.osmo_user_left, d.getVisibleName(), group.getVisibleName(app))).append("\n");
+ }
disconnectImpl(d);
} else if(!d.isActive()) {
+ if(group.name != null) {
+ b.append(app.getString(R.string.osmo_user_joined, d.getVisibleName(), group.getVisibleName(app))).append("\n");
+ }
connectDeviceImpl(d);
}
}
+ if(b.length() > 0 && app.getSettings().OSMO_SHOW_GROUP_NOTIFICATIONS.get()){
+ app.showToastMessage(b.toString().trim());
+ }
storage.save();
}
processed = true;
@@ -277,11 +297,19 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
device.lastOnline = o.getLong(LAST_ONLINE);
}
if (o.has(USER_COLOR)) {
- device.serverColor = o.getInt(USER_COLOR);
+ device.serverColor = net.osmand.util.Algorithms.parseColor(o.getString(USER_COLOR));
}
delta.add(device);
}
}
+ if(obj.has(TRACK)){
+ JSONArray ar = obj.getJSONArray(TRACK);
+ JSONObject[] a = new JSONObject[ar.length()];
+ for(int i = 0; i < a.length; i++) {
+ a[i] = (JSONObject) ar.get(i);
+ }
+ plugin.getDownloadGpxTask(true).execute(a);
+ }
if(deleteUsers) {
for(OsMoDevice s : toDelete.values()) {
s.deleted = System.currentTimeMillis();
@@ -318,13 +346,17 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
}
storage.save();
}
+ public void setGenColor(OsMoDevice device, int genColor) {
+ device.genColor = genColor;
+ storage.save();
+ }
- public OsMoDevice addConnectedDevice(String trackerId, String nameUser, int userColor) {
+ public OsMoDevice addConnectedDevice(String trackerId, String nameUser, int genColor) {
OsMoDevice us = new OsMoDevice();
us.group = storage.getMainGroup();
us.trackerId = trackerId;
us.userName = nameUser;
- us.userColor = userColor;
+ us.genColor = genColor;
us.group.users.put(trackerId, us);
connectDeviceImpl(us);
storage.save();
@@ -340,7 +372,7 @@ public class OsMoGroups implements OsMoReactor, OsmoTrackerListener {
}
g.userName = userName;
service.pushCommand(op);
- return op;
+ return "GROUP_JOIN:"+groupId;
}
public String leaveGroup(OsMoGroup group) {
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsActivity.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsActivity.java
index cc8a07e99c..7db76fb355 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsActivity.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsActivity.java
@@ -363,7 +363,7 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
createMenuItem(menu, GROUP_INFO, R.string.osmo_group_info, R.drawable.ic_action_info_light, R.drawable.ic_action_info_dark,
MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
- if (device == null || device.getGroup().isMainGroup()) {
+ if ((group != null && !group.isMainGroup()) || (device != null && device.getGroup().isMainGroup())) {
createMenuItem(menu, DELETE_ACTION_ID, R.string.default_buttons_delete,
R.drawable.ic_action_delete_light, R.drawable.ic_action_delete_dark,
MenuItem.SHOW_AS_ACTION_IF_ROOM);
@@ -958,7 +958,7 @@ public class OsMoGroupsActivity extends OsmandExpandableListActivity implements
int activeColor = model.getColor();
if (activeColor == 0) {
activeColor = getRandomColor();
- osMoPlugin.getGroups().setDeviceProperties(model, model.getVisibleName(), activeColor);
+ osMoPlugin.getGroups().setGenColor(model, activeColor);
}
//Location location = tracker.getLastLocation(model.trackerId);
if (location == null || mapLocation == null) {
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsStorage.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsStorage.java
index a66f688023..a4362021bd 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsStorage.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroupsStorage.java
@@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
import net.osmand.Location;
import net.osmand.data.LatLon;
@@ -25,7 +26,8 @@ public class OsMoGroupsStorage {
private static final String GROUP_ID = "group_id";
private static final String TRACKER_ID = "trackerId";
private static final String USER_NAME = "userName";
- private static final String USER_COLOR = "userColor";
+ private static final String USER_COLOR = "userSetColor";
+ private static final String GEN_COLOR = "genColor";
private static final String SERVER_COLOR = "serverColor";
private static final String DESCRIPTION = "description";
private static final String POLICY = "policy";
@@ -146,6 +148,9 @@ public class OsMoGroupsStorage {
if (u.userColor != 0) {
obj.put(USER_COLOR, u.userColor);
}
+ if (u.genColor != 0) {
+ obj.put(GEN_COLOR, u.genColor);
+ }
if (u.serverColor != 0) {
obj.put(SERVER_COLOR, u.serverColor);
}
@@ -183,6 +188,9 @@ public class OsMoGroupsStorage {
if(o.has(USER_COLOR)) {
user.userColor = o.getInt(USER_COLOR);
}
+ if(o.has(GEN_COLOR)) {
+ user.genColor = o.getInt(GEN_COLOR);
+ }
if(o.has(DELETED)) {
user.deleted = o.getLong(DELETED);
}
@@ -274,9 +282,6 @@ public class OsMoGroupsStorage {
OsMoDevice d = users.get(trackerId);
if(d != null) {
d.setLastLocation(location);
- if(location != null) {
- d.setLastOnline(location.getTime());
- }
}
return d;
}
@@ -310,12 +315,14 @@ public class OsMoGroupsStorage {
protected String userName;
protected int serverColor;
protected int userColor;
+ protected int genColor;
protected String trackerId;
protected boolean enabled;
protected boolean active;
protected long deleted;
protected OsMoGroup group ;
+ protected ConcurrentLinkedQueue previousLocations = new java.util.concurrent.ConcurrentLinkedQueue();
protected List messages = new ArrayList();
protected long lastOnline;
protected Location lastLocation;
@@ -325,8 +332,21 @@ public class OsMoGroupsStorage {
return messages;
}
+ public ConcurrentLinkedQueue getPreviousLocations(long threshold) {
+ while(!previousLocations.isEmpty() && previousLocations.peek().getTime() < threshold) {
+ previousLocations.poll();
+ }
+ return previousLocations;
+ }
+
public void setLastLocation(Location lastLocation) {
+ if(this.lastLocation != null) {
+ previousLocations.add(this.lastLocation);
+ }
this.lastLocation = lastLocation;
+ if (lastLocation != null) {
+ setLastOnline(lastLocation.getTime());
+ }
}
public Location getLastLocation() {
@@ -336,6 +356,7 @@ public class OsMoGroupsStorage {
public void setLastOnline(long lastOnline) {
this.lastOnline = lastOnline;
}
+
public long getLastOnline() {
return lastOnline;
}
@@ -369,7 +390,7 @@ public class OsMoGroupsStorage {
if(serverColor != 0) {
return serverColor ;
}
- return userColor;
+ return genColor;
}
public String getVisibleName(){
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java
index 12c56a1e25..20ee58dacc 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java
@@ -1,18 +1,27 @@
package net.osmand.plus.osmo;
-import java.text.SimpleDateFormat;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import net.osmand.IndexConstants;
import net.osmand.Location;
+import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
+import net.osmand.plus.GPXUtilities;
+import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SettingsActivity;
+import net.osmand.plus.download.DownloadFileHelper;
import net.osmand.plus.osmo.OsMoGroupsStorage.OsMoDevice;
import net.osmand.plus.osmo.OsMoService.SessionInfo;
import net.osmand.plus.views.MapInfoLayer;
@@ -22,10 +31,16 @@ import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.BaseMapWidget;
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
+
+import org.apache.commons.logging.Log;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
@@ -40,16 +55,16 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
private OsMoGroups groups;
private BaseMapWidget osmoControl;
private OsMoPositionLayer olayer;
-
- // 2014-05-27 23:11:40
- public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ protected MapActivity mapActivity;
+
+ private final static Log log = PlatformUtil.getLog(OsMoPlugin.class);
public OsMoPlugin(final OsmandApplication app) {
- service = new OsMoService(app);
+ service = new OsMoService(app, this);
tracker = new OsMoTracker(service, app.getSettings().OSMO_SAVE_TRACK_INTERVAL,
app.getSettings().OSMO_AUTO_SEND_LOCATIONS);
- new OsMoControlDevice(app, service, tracker);
- groups = new OsMoGroups(service, tracker, app.getSettings());
+ new OsMoControlDevice(app, this, service, tracker);
+ groups = new OsMoGroups(this, service, tracker, app);
this.app = app;
ApplicationMode.regWidget("osmo_control", (ApplicationMode[])null);
}
@@ -80,6 +95,8 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
public String getName() {
return app.getString(R.string.osmo_plugin_name);
}
+
+
@Override
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
@@ -157,13 +174,15 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
@Override
public void mapActivityPause(MapActivity activity) {
groups.setUiListener(null);
+ mapActivity = activity;
}
@Override
public void mapActivityResume(MapActivity activity) {
- if(olayer != null) {
+ if (olayer != null) {
groups.setUiListener(olayer);
}
+ mapActivity = null;
}
/**
@@ -305,6 +324,71 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
return service;
}
-
+ public AsyncTask getDownloadGpxTask(final boolean makeVisible) {
+
+ return new AsyncTask (){
+
+ @Override
+ protected String doInBackground(JSONObject... params) {
+ final File fl = app.getAppPath(IndexConstants.GPX_INDEX_DIR+"/osmo");
+ if(!fl.exists()) {
+ fl.mkdirs();
+ }
+ String errors = "";
+ for(JSONObject obj : params) {
+ try {
+ File f = new File(fl, obj.getString("name")+".gpx");
+ long timestamp = obj.getLong("created") * 1000;
+ boolean visible = obj.has("visible");
+ boolean changed = false;
+ if(!f.exists() || (f.lastModified() != timestamp) ) {
+ boolean sizeEqual = f.exists() && obj.has("size") && obj.getLong("size") == f.length();
+ if(sizeEqual && !f.setLastModified(timestamp - 1)){
+ // false alarm
+ } else {
+ changed = true;
+ String url = obj.getString("url");
+ log.info("Download gpx " + url);
+ DownloadFileHelper df = new DownloadFileHelper(app);
+ InputStream is = df.getInputStreamToDownload(new URL(url), false);
+ FileOutputStream fout = new FileOutputStream(f);
+ byte[] buf = new byte[1024];
+ int k;
+ while ((k = is.read(buf)) >= 0) {
+ fout.write(buf, 0, k);
+ }
+ fout.close();
+ is.close();
+ if(!f.setLastModified(timestamp)) {
+ log.error("Timestamp updates are not supported");
+ }
+ }
+ }
+ if(visible && (changed || makeVisible)) {
+ GPXFile selectGPXFile = GPXUtilities.loadGPXFile(app, f);
+ app.setGpxFileToDisplay(selectGPXFile, app.getSettings().SHOW_CURRENT_GPX_TRACK.get());
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ errors += e.getMessage() +"\n";
+ } catch (IOException e) {
+ e.printStackTrace();
+ errors += e.getMessage() +"\n";
+ }
+ }
+ return errors;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ if(result.length() > 0) {
+ app.showToastMessage(app.getString(R.string.osmo_io_error)+ result);
+ }
+ }
+
+ };
+
+ }
+
}
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPositionLayer.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPositionLayer.java
index 3c4c649182..486c9a0e67 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPositionLayer.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPositionLayer.java
@@ -2,7 +2,9 @@ package net.osmand.plus.osmo;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
import net.osmand.Location;
import net.osmand.access.AccessibleToast;
@@ -25,7 +27,10 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
+import android.graphics.Path;
import android.graphics.PointF;
import android.os.Handler;
import android.util.DisplayMetrics;
@@ -36,16 +41,19 @@ import android.widget.Toast;
* Class represents a layer for osmo positions
*
*/
-public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider, OsMoGroupsUIListener {
-
+public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider, OsMoGroupsUIListener,
+ ContextMenuLayer.IContextMenuProviderSelection{
+
private DisplayMetrics dm;
private final MapActivity map;
private OsmandMapTileView view;
- private Paint pointAltUI;
- private Paint point;
+ private Paint pointInnerCircle;
+ private Paint pointOuter;
private OsMoPlugin plugin;
private final static float startZoom = 7;
private Handler uiHandler;
+ private Paint paintPath;
+ private Path pth;
public OsMoPositionLayer(MapActivity map, OsMoPlugin plugin) {
this.map = map;
@@ -60,14 +68,24 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
- pointAltUI = new Paint();
- pointAltUI.setColor(view.getApplication().getResources().getColor(R.color.poi_background));
- pointAltUI.setStyle(Style.FILL);
+ pointInnerCircle = new Paint();
+ pointInnerCircle.setColor(view.getApplication().getResources().getColor(R.color.poi_background));
+ pointInnerCircle.setStyle(Style.FILL);
+ pointInnerCircle.setAntiAlias(true);
- point = new Paint();
- point.setColor(Color.DKGRAY);
- point.setAntiAlias(true);
- point.setStyle(Style.FILL_AND_STROKE);
+ paintPath = new Paint();
+ paintPath.setStyle(Style.STROKE);
+ paintPath.setStrokeWidth(14);
+ paintPath.setAntiAlias(true);
+ paintPath.setStrokeCap(Cap.ROUND);
+ paintPath.setStrokeJoin(Join.ROUND);
+
+ pth = new Path();
+
+ pointOuter = new Paint();
+ pointOuter.setColor(Color.GRAY);
+ pointOuter.setAntiAlias(true);
+ pointOuter.setStyle(Style.FILL_AND_STROKE);
}
public Collection getTrackingDevices() {
@@ -79,30 +97,48 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
final float zoom = tb.getZoom() + tb.getZoomScale();
if(zoom < startZoom){
r = 0;
- } else if(zoom <= 15){
+ } else if(zoom <= 11){
r = 10;
- } else if(zoom <= 16){
- r = 14;
- } else if(zoom <= 17){
- r = 16;
+ } else if(zoom <= 14){
+ r = 12;
} else {
- r = 18;
+ r = 14;
}
return (int) (r * tb.getDensity());
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
- final int r = getRadiusPoi(tb) * 3 / 4;
+ final int r = getRadiusPoi(tb);
+ long treshold = System.currentTimeMillis() - 15000;
for (OsMoDevice t : getTrackingDevices()) {
Location l = t.getLastLocation();
if (l != null) {
+ ConcurrentLinkedQueue plocations = t.getPreviousLocations(treshold);
int x = (int) tb.getPixXFromLatLon(l.getLatitude(), l.getLongitude());
int y = (int) tb.getPixYFromLatLon(l.getLatitude(), l.getLongitude());
-
- pointAltUI.setColor(t.getColor());
- canvas.drawCircle(x, y, r , point);
- canvas.drawCircle(x, y, r - 2, pointAltUI);
+ if (plocations.size() > 0) {
+ pth.rewind();
+ Iterator it = plocations.iterator();
+ boolean f= true;
+ while (it.hasNext()) {
+ Location lo = it.next();
+ int xt = (int) tb.getPixXFromLatLon(lo.getLatitude(), lo.getLongitude());
+ int yt = (int) tb.getPixYFromLatLon(lo.getLatitude(), lo.getLongitude());
+ if(f) {
+ f = false;
+ pth.moveTo(xt, yt);
+ } else{
+ pth.lineTo(xt, yt);
+ }
+ }
+ pth.lineTo(x, y);
+ paintPath.setColor(t.getColor());
+ canvas.drawPath(pth, paintPath);
+ }
+ pointInnerCircle.setColor(t.getColor());
+ canvas.drawCircle(x, y, r + 2, pointOuter);
+ canvas.drawCircle(x, y, r - 2, pointInnerCircle);
}
}
}
@@ -152,9 +188,11 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
if (o instanceof OsMoDevice) {
String d = map.getString(R.string.osmo_user_name) + " " + ((OsMoDevice) o).getVisibleName();
final Location l = ((OsMoDevice) o).getLastLocation();
+ float speed = 0;
if(l != null && l.hasSpeed()) {
- d += "\n"+ OsmAndFormatter.getFormattedSpeed(l.getSpeed(), map.getMyApplication());
+ speed = l.getSpeed();
}
+ d += "\n"+ OsmAndFormatter.getFormattedSpeed(speed, map.getMyApplication());
return d;
}
return null;
@@ -162,10 +200,10 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
@Override
public String getObjectName(Object o) {
- if(o instanceof OsMoDevice) {
- return map.getString(R.string.osmo_user_name) + " " + ((OsMoDevice) o).getVisibleName();
- }
- return null;
+// if(o instanceof OsMoDevice) {
+// return map.getString(R.string.osmo_user_name) + " " + ((OsMoDevice) o).getVisibleName();
+// }
+ return getObjectDescription(o);
}
public void refresh() {
@@ -232,7 +270,6 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
@Override
public void deviceLocationChanged(final OsMoDevice device) {
- boolean sameId = Algorithms.objectEquals(followTrackerId, device.trackerId);
boolean sameDestId = Algorithms.objectEquals(followDestinationId, device.trackerId);
Location l = device.getLastLocation();
if(sameDestId && l != null) {
@@ -249,19 +286,30 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
targets.navigateToPoint(lt, true, -1);
}
}
- if(sameId && !schedule && l != null) {
- schedule = true;
+
+ boolean sameId = Algorithms.objectEquals(followTrackerId, device.trackerId);
+ if(sameId && !schedule && l != null) {
ContextMenuLayer cl = map.getMapLayers().getContextMenuLayer();
- final boolean sameObject = Algorithms.objectEquals(device, cl.getFirstSelectedObject()) && cl.isVisible();
+ final boolean sameObject;
+ if(cl.getFirstSelectedObject() instanceof OsMoDevice && cl.isVisible()) {
+ sameObject = Algorithms.objectEquals(device.trackerId, ((OsMoDevice) cl.getFirstSelectedObject()).trackerId) ;
+ } else{
+ sameObject = false;
+ }
LatLon mapLoc = new LatLon(map.getMapView().getLatitude(), map.getMapView().getLongitude());
final boolean centered = Algorithms.objectEquals(followMapLocation, mapLoc);
if(sameObject || centered) {
+ final LatLon loc;
if(centered ) {
- followMapLocation = new LatLon(l.getLatitude(), l.getLongitude());
+ loc = new LatLon(l.getLatitude(), l.getLongitude());
} else if(!map.getMapView().getAnimatedDraggingThread().isAnimating()) {
// disable tracking
- followMapLocation = null;
+ loc = null;
+ } else {
+ loc = followMapLocation;
}
+ followMapLocation = loc;
+ schedule = true;
uiHandler.postDelayed(new Runnable() {
@Override
@@ -274,8 +322,8 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
cl.setSelectedObject(device);
}
if (centered) {
- map.getMapView().setLatLon(followMapLocation.getLatitude(),
- followMapLocation.getLongitude());
+ map.getMapView().setLatLon(loc.getLatitude(),
+ loc.getLongitude());
}
map.getMapView().refreshMap();
}
@@ -286,6 +334,22 @@ public class OsMoPositionLayer extends OsmandMapLayer implements ContextMenuLaye
}
}
}
+
+ @Override
+ public void setSelectedObject(Object o) {
+ if(o instanceof OsMoDevice) {
+ followTrackerId = ((OsMoDevice) o).getTrackerId();
+ }
+ }
+
+ @Override
+ public void clearSelectedObjects() {
+ LatLon mapLoc = new LatLon(map.getMapView().getLatitude(), map.getMapView().getLongitude());
+ final boolean centered = Algorithms.objectEquals(followMapLocation, mapLoc);
+ if(!centered && followTrackerId != null) {
+ followTrackerId = null;
+ }
+ }
}
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java
index 72e656686d..db86275b5b 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java
@@ -10,6 +10,7 @@ import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.osmand.PlatformUtil;
+import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
@@ -27,6 +28,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import android.os.AsyncTask;
import android.os.Build;
import android.provider.Settings.Secure;
@@ -41,12 +43,14 @@ public class OsMoService implements OsMoReactor {
public static final String SHARE_TRACKER_URL = "http://z.osmo.mobi/connect?id=";
public static final String SHARE_GROUP_URL = "http://z.osmo.mobi/join?id=";
public static final String TRACK_URL = "http://test1342.osmo.mobi/u/";
- private String lastRegistrationError = null;
+ private String lastRegistrationError = null;
+ private OsMoPlugin plugin;
- public OsMoService(OsmandApplication app) {
+ public OsMoService(OsmandApplication app, OsMoPlugin plugin) {
this.app = app;
+ this.plugin = plugin;
listReactors.add(this);
}
@@ -70,7 +74,7 @@ public class OsMoService implements OsMoReactor {
if(thread == null) {
return Collections.emptyList();
}
- return new ArrayList(thread.getLast100Commands());
+ return new ArrayList(thread.getLastCommands());
}
@@ -242,6 +246,7 @@ public class OsMoService implements OsMoReactor {
app.showToastMessage(app.getString(R.string.osmo_io_error) + string);
}
+
public void pushCommand(String cmd) {
commands.add(cmd);
}
@@ -269,13 +274,27 @@ public class OsMoService implements OsMoReactor {
si.motd = data;
}
return true;
+ } else if(command.equals("TRACK_GET")) {
+ try {
+ JSONArray ar = new JSONArray(data);
+ AsyncTask task = plugin.getDownloadGpxTask(false);
+ JSONObject[] a = new JSONObject[ar.length()];
+ for(int i = 0; i < a.length; i++) {
+ a[i] = (JSONObject) ar.get(i);
+ }
+ task.execute(a);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ showErrorMessage(e.getMessage());
+ }
}
return false;
}
+
@Override
public void reconnect() {
-
+ pushCommand("TRACK_GET");
}
public void reconnectToServer() {
diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java
index 7fd55ccc1d..e10da8cfc2 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java
@@ -66,7 +66,8 @@ public class OsMoThread {
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
- private ConcurrentLinkedQueue last100Commands = new ConcurrentLinkedQueue();
+ private ConcurrentLinkedQueue lastCommands = new ConcurrentLinkedQueue();
+ private final static int STACK_CMD = 30;
@@ -91,6 +92,7 @@ public class OsMoThread {
this.activeChannel = null;
authorized = 0;
reconnect = false;
+ pingSent = 0;
failures = 0;
lastSendCommand = 0;
selector = Selector.open();
@@ -276,7 +278,11 @@ public class OsMoThread {
if(obj != null && obj.has("error")) {
error = true;
try {
- service.showErrorMessage(obj.getString("error"));
+ String s = obj.getString("error");
+ if(obj.has("error_description")) {
+ s += " " +obj.getString("error_description");
+ }
+ service.showErrorMessage(s);
} catch (JSONException e) {
e.printStackTrace();
}
@@ -378,23 +384,30 @@ public class OsMoThread {
return ByteBuffer.wrap(prepareCommand(l).toString().getBytes("UTF-8"));
}
}
- if(System.currentTimeMillis() - lastSendCommand > TIMEOUT_TO_PING) {
- if(pingSent == 0) {
+ final long interval = System.currentTimeMillis() - lastSendCommand;
+ if(interval > TIMEOUT_TO_PING) {
+ final long pingInterval = System.currentTimeMillis() - pingSent;
+ if(pingSent == 0 || pingInterval > TIMEOUT_TO_PING) {
pingSent = System.currentTimeMillis();
cmd(PING_CMD, true);
return ByteBuffer.wrap(prepareCommand(PING_CMD).toString().getBytes("UTF-8"));
}
+ } else if(pingSent != 0) {
+ pingSent = 0;
}
return null;
}
- public ConcurrentLinkedQueue getLast100Commands() {
- return last100Commands;
+ public ConcurrentLinkedQueue getLastCommands() {
+ return lastCommands;
}
private void cmd(String cmd, boolean send) {
log.info("OsMO" + (send ? "> " : ">> ") + cmd);
- last100Commands.add((send ? "> " : ">> ") + df.format(new Date()) + " " + cmd);
+ lastCommands.add((send ? "> " : ">> ") + df.format(new Date()) + " " + cmd);
+ while(lastCommands.size() > STACK_CMD) {
+ lastCommands.poll();
+ }
}
public SessionInfo getSessionInfo() {
diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
index f74fc35198..bdd000db44 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
@@ -28,7 +28,6 @@ public class SettingsOsMoActivity extends SettingsBaseActivity {
private Preference debugPref;
private Preference trackerId;
- private CheckBoxPreference sendLocationsref;
public static final int[] SECONDS = new int[] {0, 1, 2, 3, 5, 10, 15, 30, 60, 90};
public static final int[] MINUTES = new int[] {2, 3, 5};
@@ -48,7 +47,7 @@ public class SettingsOsMoActivity extends SettingsBaseActivity {
trackerId.setOnPreferenceClickListener(this);
grp.addPreference(trackerId);
- sendLocationsref = createCheckBoxPreference(settings.OSMO_AUTO_SEND_LOCATIONS);
+ CheckBoxPreference sendLocationsref = createCheckBoxPreference(settings.OSMO_AUTO_SEND_LOCATIONS);
sendLocationsref.setTitle(R.string.osmo_auto_send_locations);
sendLocationsref.setSummary(R.string.osmo_auto_send_locations_descr);
grp.addPreference(sendLocationsref);
@@ -56,6 +55,11 @@ public class SettingsOsMoActivity extends SettingsBaseActivity {
grp.addPreference(createTimeListPreference(settings.OSMO_SAVE_TRACK_INTERVAL, SECONDS,
MINUTES, 1000, R.string.osmo_track_interval, R.string.osmo_track_interval_descr));
+ CheckBoxPreference showGroupNotifiations = createCheckBoxPreference(settings.OSMO_SHOW_GROUP_NOTIFICATIONS);
+ sendLocationsref.setTitle(R.string.osmo_show_group_notifications);
+ sendLocationsref.setSummary(R.string.osmo_show_group_notifications_descr);
+ grp.addPreference(sendLocationsref);
+
debugPref = new Preference(this);
debugPref.setTitle(R.string.osmo_settings_debug);
debugPref.setOnPreferenceClickListener(this);
diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
index 73dd4ecba6..1ff0324c5b 100644
--- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
@@ -40,7 +40,17 @@ public class ContextMenuLayer extends OsmandMapLayer {
public String getObjectName(Object o);
+
}
+
+ public interface IContextMenuProviderSelection {
+
+ public void setSelectedObject(Object o);
+
+ public void clearSelectedObjects();
+
+ }
+
private static final String KEY_LAT_LAN = "context_menu_lat_lon";
private static final String KEY_DESCRIPTION = "context_menu_description";
private static final String KEY_SELECTED_OBJECTS = "context_menu_selected_objects";
@@ -189,17 +199,29 @@ public class ContextMenuLayer extends OsmandMapLayer {
public void setSelections(Map