This commit is contained in:
unknown 2014-06-01 21:33:41 +03:00
commit 329894db95
15 changed files with 384 additions and 82 deletions

View file

@ -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++) {

View file

@ -1546,7 +1546,7 @@
<string name="interrupt_music_descr">Прерывание музыки во время объявления</string>
<string name="interrupt_music">Прерывание музыки</string>
<string name="share_route_as_gpx">Поделиться маршрутом используя файл GPX</string>
<string name="osmo_settings_uuid">Уникальный ID устройства</string>
<string name="osmo_settings_uuid">Ключ доступа</string>
<string name="osmo_settings_descr">Настройка параметров мониторинга и установка персонального канала мониторинга</string>
<string name="osmo_plugin_description">OpenStreetMap-Monitoring - продвинутый живой мониторинг с множеством средств удалённого контроля http://osmo.mobi</string>
<string name="osmo_plugin_name">OsMo (Продвинутый онлайн-мониторинг)</string>
@ -1661,5 +1661,5 @@ OsmAnd - открытый источник и активно развается.
<string name="color_lightblue">голубой</string>
<string name="color_blue">синий</string>
<string name="color_magenta">маджента</string>
<string name="color_green">зелёный</string>
</resources>

View file

@ -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
-->
<string name="osmo_user_joined">User %1$s joined group %2$s</string>
<string name="osmo_user_left">User %1$s left group %2$s</string>
<string name="osmo_show_group_notifications">Show group notifications</string>
<string name="osmo_show_group_notifications_descr">Show toast messages when user joins or leavs the group</string>
<string name="osmo_follow">Follow</string>
<string name="osmo_sign_in">Sign in</string>
<string name="osmo_create_groups_confirm">In order to create groups you need to be a registered user of OsMo.</string>

View file

@ -834,6 +834,8 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal();
public final OsmandPreference<Boolean> OSMO_SHOW_GROUP_NOTIFICATIONS = new BooleanPreference("osmo_show_toast_notifications", true).makeGlobal();
public final CommonPreference<Integer> OSMO_SAVE_TRACK_INTERVAL = new IntPreference("osmo_save_track_interval", 5000).makeGlobal().cache();
public final OsmandPreference<String> OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal();

View file

@ -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;

View file

@ -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;
}

View file

@ -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<OsMoDevice> 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) {

View file

@ -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) {

View file

@ -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<Location> previousLocations = new java.util.concurrent.ConcurrentLinkedQueue<Location>();
protected List<OsMoMessage> messages = new ArrayList<OsMoMessage>();
protected long lastOnline;
protected Location lastLocation;
@ -325,8 +332,21 @@ public class OsMoGroupsStorage {
return messages;
}
public ConcurrentLinkedQueue<Location> 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(){

View file

@ -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;
protected MapActivity mapActivity;
// 2014-05-27 23:11:40
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
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);
}
@ -81,6 +96,8 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
return app.getString(R.string.osmo_plugin_name);
}
@Override
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
// registerLayers(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<JSONObject, GPXFile, String> getDownloadGpxTask(final boolean makeVisible) {
return new AsyncTask<JSONObject, GPXFile, String> (){
@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);
}
}
};
}
}

View file

@ -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<OsMoDevice> 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<Location> 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<Location> 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();
}
@ -287,5 +335,21 @@ 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;
}
}
}

View file

@ -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;
@ -42,11 +44,13 @@ public class OsMoService implements OsMoReactor {
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 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<String>(thread.getLast100Commands());
return new ArrayList<String>(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<JSONObject, GPXFile, String> 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() {

View file

@ -66,7 +66,8 @@ public class OsMoThread {
private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
private ConcurrentLinkedQueue<String> last100Commands = new ConcurrentLinkedQueue<String>();
private ConcurrentLinkedQueue<String> lastCommands = new ConcurrentLinkedQueue<String>();
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<String> getLast100Commands() {
return last100Commands;
public ConcurrentLinkedQueue<String> 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() {

View file

@ -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);

View file

@ -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<Object, IContextMenuProvider> selections) {
clearSelectedObjects();
if (selections != null) {
selectedObjects = selections;
} else {
selectedObjects.clear();
}
if (!selectedObjects.isEmpty()) {
Entry<Object, IContextMenuProvider> e = selectedObjects.entrySet().iterator().next();
latLon = e.getValue().getObjectLocation(e.getKey());
if(e.getValue() instanceof IContextMenuProviderSelection){
((IContextMenuProviderSelection) e.getValue()).setSelectedObject(e.getKey());
}
}
}
private void clearSelectedObjects() {
for(IContextMenuProvider p : this.selectedObjects.values()) {
if(p instanceof IContextMenuProviderSelection){
((IContextMenuProviderSelection) p).clearSelectedObjects();
}
}
selectedObjects.clear();
}
@Override
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
if ((Build.VERSION.SDK_INT < 14) && !view.getSettings().SCROLL_MAP_BY_GESTURES.get()) {
@ -223,15 +245,19 @@ public class ContextMenuLayer extends OsmandMapLayer {
public LatLon selectObjectsForContextMenu(RotatedTileBox tileBox, PointF point) {
final double lat = tileBox.getLatFromPixel((int) point.x, (int) point.y);
final double lon = tileBox.getLonFromPixel((int) point.x, (int) point.y);
selectedObjects.clear();
clearSelectedObjects();
List<Object> s = new ArrayList<Object>();
LatLon latLon = null;
for(OsmandMapLayer l : view.getLayers()){
if(l instanceof ContextMenuLayer.IContextMenuProvider){
for(OsmandMapLayer lt : view.getLayers()){
if(lt instanceof ContextMenuLayer.IContextMenuProvider){
s.clear();
((ContextMenuLayer.IContextMenuProvider) l).collectObjectsFromPoint(point, tileBox, s);
final IContextMenuProvider l = (ContextMenuLayer.IContextMenuProvider) lt;
l.collectObjectsFromPoint(point, tileBox, s);
for(Object o : s) {
selectedObjects.put(o, ((ContextMenuLayer.IContextMenuProvider) l));
selectedObjects.put(o, l);
if(l instanceof IContextMenuProviderSelection){
((IContextMenuProviderSelection) l).setSelectedObject(o);
}
if(latLon == null) {
latLon = ((ContextMenuLayer.IContextMenuProvider) l).getObjectLocation(o);
}
@ -382,13 +408,16 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
public void setSelectedObject(Object toShow) {
selectedObjects.clear();
clearSelectedObjects();
if(toShow != null){
for(OsmandMapLayer l : view.getLayers()){
if(l instanceof ContextMenuLayer.IContextMenuProvider){
String des = ((ContextMenuLayer.IContextMenuProvider) l).getObjectDescription(toShow);
if(des != null) {
selectedObjects.put(toShow, (IContextMenuProvider) l);
if(l instanceof IContextMenuProviderSelection){
((IContextMenuProviderSelection) l).setSelectedObject(toShow);
}
}
}
}