From 3c7a418707c89a85a89811821081d118ec16c254 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Fri, 16 May 2014 01:36:39 +0300 Subject: [PATCH 01/17] Add authorization --- OsmAnd/res/values/strings.xml | 1 + .../src/net/osmand/plus/OsmandSettings.java | 2 + .../src/net/osmand/plus/osmo/OsMoPlugin.java | 102 ++++++++++++++- .../src/net/osmand/plus/osmo/OsMoService.java | 16 ++- .../src/net/osmand/plus/osmo/OsMoThread.java | 120 ++++++++++++++---- .../src/net/osmand/plus/osmo/OsMoTracker.java | 2 +- .../plus/osmo/SettingsOsMoActivity.java | 29 ++++- 7 files changed, 230 insertions(+), 42 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 347b324f54..c1bced8245 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 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 --> + Registering device... OSMo connection problem : Stop OSMo Start OSMo diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 1d165b248f..5d650faf49 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -824,6 +824,8 @@ public class OsmandSettings { public final OsmandPreference MAP_INFO_CONTROLS = new StringPreference("map_info_controls", "").makeProfile(); + public final OsmandPreference OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal(); + // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference("debug_rendering", false).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index 1adf4cd150..20272e4eba 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -1,5 +1,12 @@ package net.osmand.plus.osmo; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.plus.ContextMenuAdapter; @@ -7,6 +14,7 @@ import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; +import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.views.MonitoringInfoControl; @@ -14,25 +22,39 @@ import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices import net.osmand.plus.views.OsmandMapTileView; import org.apache.commons.logging.Log; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONException; +import org.json.JSONObject; +import android.app.Activity; +import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.os.AsyncTask; +import android.os.Build; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; -import android.provider.Settings; +import android.provider.Settings.Secure; public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices { private OsmandApplication app; public static final String ID = "osmand.osmo"; - //private static final Log log = PlatformUtil.getLog(OsMoPlugin.class); + private static final Log log = PlatformUtil.getLog(OsMoPlugin.class); private OsMoService service; private OsMoTracker tracker; public OsMoPlugin(final OsmandApplication app) { - service = new OsMoService(); + service = new OsMoService(app); tracker = new OsMoTracker(service); this.app = app; } @@ -49,10 +71,6 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer } } - public static String getUUID(Context ctx) { - return Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.ANDROID_ID); - } - @Override public String getDescription() { return app.getString(R.string.osmo_plugin_description); @@ -73,17 +91,87 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer } } + public AsyncTask + getRegisterDeviceTask(final Context uiContext, final Runnable postAction) { + return new AsyncTask() { + private ProgressDialog dlg; + protected void onPreExecute() { + dlg = ProgressDialog.show(uiContext, "", app.getString(R.string.osmo_register_device)); + }; + @Override + protected void onPostExecute(Exception result) { + if (result != null) { + result.printStackTrace(); + app.showToastMessage(app.getString(R.string.osmo_io_error) + result.getMessage()); + } else if(postAction != null) { + postAction.run(); + } + } + + @Override + protected Exception doInBackground(Void... params) { + if(dlg.isShowing()) { + dlg.dismiss(); + } + return OsmandPlugin.getEnabledPlugin(OsMoPlugin.class).registerOsmoDeviceKey(); + } + }; + } + + private Exception registerOsmoDeviceKey() { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); + nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); + nameValuePairs.add(new BasicNameValuePair("imei", "0")); + nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); + nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + return new RuntimeException(obj.getString("error")); + } + app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); + return null; + } catch (ClientProtocolException e) { + return e; + } catch (IOException e) { + return e; + } catch (JSONException e) { + return e; + } + } @Override public void addMonitorActions(ContextMenuAdapter qa, MonitoringInfoControl li, final OsmandMapTileView view) { final boolean off = !service.isConnected(); + qa.item(off ? R.string.osmo_mode_off : R.string.osmo_mode_on) .icon(off ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) .listen(new OnContextMenuClick() { @Override public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) { + if(app.getSettings().OSMO_DEVICE_KEY.get().length() == 0) { + getRegisterDeviceTask(view.getContext(), new Runnable() { + public void run() { + service.connect(true); + } + }); + return; + } if(off) { service.connect(true); } else { diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 65a6fdbe13..8abe32501a 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -2,25 +2,29 @@ package net.osmand.plus.osmo; import java.util.List; +import org.json.JSONObject; + +import net.osmand.plus.OsmandApplication; + public class OsMoService { - //public static int NUMBER_OF_TRIES_TO_RECONNECT = 20; - private OsMoThread thread; private List listSenders = new java.util.concurrent.CopyOnWriteArrayList(); private List listReactors = new java.util.concurrent.CopyOnWriteArrayList(); + private OsmandApplication app; public interface OsMoSender { - public String nextSendCommand(); + public String nextSendCommand(OsMoThread tracker); } public interface OsMoReactor { - public boolean acceptCommand(String command); + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread tracker); } - public OsMoService() { + public OsMoService(OsmandApplication app) { + this.app = app; } public boolean isConnected() { @@ -34,7 +38,7 @@ public class OsMoService { } thread.stopConnection(); } - thread = new OsMoThread(listSenders, listReactors); + thread = new OsMoThread(app, listSenders, listReactors); return true; } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index f4d36cefd1..76777bc432 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -10,17 +10,25 @@ import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import java.util.TreeMap; import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; import net.osmand.plus.osmo.OsMoService.OsMoReactor; import net.osmand.plus.osmo.OsMoService.OsMoSender; import org.apache.commons.logging.Log; +import org.json.JSONException; +import org.json.JSONObject; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; +import android.provider.Settings.Secure; public class OsMoThread { private static String TRACKER_SERVER = "srv.osmo.mobi"; @@ -45,13 +53,18 @@ public class OsMoThread { private List listSenders; private List listReactors; + private boolean authorized; + private OsmandApplication ctx; + private String authorizationCommand = null; private SocketChannel activeChannel; private ByteBuffer pendingSendCommand; private String readCommand = ""; private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048); private LinkedList queueOfMessages = new LinkedList(); + - public OsMoThread(List listSenders, List listReactors) { + public OsMoThread(OsmandApplication ctx, List listSenders, List listReactors) { + this.ctx = ctx; this.listSenders = listSenders; this.listReactors = listReactors; // start thread to receive events from OSMO @@ -78,6 +91,8 @@ public class OsMoThread { protected void initConnection() throws IOException { try { + authorized = false; + authorizationCommand = getAuthorizationCmd(); selector = Selector.open(); connectionStarted = System.currentTimeMillis(); activeChannel = SocketChannel.open(); @@ -89,6 +104,28 @@ public class OsMoThread { throw e; } } + + public String format(String cmd, Map params) { + JSONObject json; + try { + json = new JSONObject(); + Iterator> it = params.entrySet().iterator(); + while(it.hasNext()) { + Entry e = it.next(); + json.put(e.getKey(), e.getValue()); + } + return cmd + "|"+json.toString(); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + private String getAuthorizationCmd() { + Map params = new TreeMap(); + params.put("protocol_version", 1); + params.put("key", ctx.getSettings().OSMO_DEVICE_KEY.get()); + return format("AUTH", params); + } public void scheduleHeartbeat(long delay) { Message msg = serviceThread.obtainMessage(); @@ -205,45 +242,84 @@ public class OsMoThread { } if (queueOfMessages.size() > 0) { - while(!queueOfMessages.isEmpty()){ - String cmd = queueOfMessages.poll(); - boolean processed = false; - for (OsMoReactor o : listReactors) { - if (o.acceptCommand(cmd)) { - processed = true; - break; - } - } - if (!processed) { - log.warn("Command not processed '" + cmd + "'"); - } - } + processReadMessages(); } } + private void processReadMessages() { + while(!queueOfMessages.isEmpty()){ + String cmd = queueOfMessages.poll(); + int k = cmd.indexOf('|'); + String header = cmd; + String data = ""; + if(k >= 0) { + header = cmd.substring(0, k); + data = cmd.substring(k + 1); + } + JSONObject obj = null; + if(data.startsWith("{")) { + try { + obj = new JSONObject(data); + } catch (JSONException e) { + e.printStackTrace(); + } + } + if(cmd.equalsIgnoreCase("AUTH")) { + if(obj != null && !obj.has("error")) { + try { + ctx.showToastMessage(ctx.getString(R.string.osmo_io_error) + obj.getString("error")); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + authorized = true; + ctx.showToastMessage("OSMo authorization successfull"); + } + continue; + } + boolean processed = false; + for (OsMoReactor o : listReactors) { + if (o.acceptCommand(header, data, obj, this)) { + processed = true; + break; + } + } + if (!processed) { + log.warn("Command not processed '" + cmd + "'"); + } + } + } + private void writeCommands() throws UnsupportedEncodingException, IOException { if (pendingSendCommand == null) { - getNewPendingSendCommand(); + pendingSendCommand = getNewPendingSendCommand(); } while (pendingSendCommand != null) { activeChannel.write(pendingSendCommand); if (!pendingSendCommand.hasRemaining()) { - pendingSendCommand = null; - getNewPendingSendCommand(); + pendingSendCommand = getNewPendingSendCommand(); } } } - private void getNewPendingSendCommand() throws UnsupportedEncodingException { + private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException { + if(authorizationCommand != null) { + String auth = authorizationCommand; + authorizationCommand = null; + return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8")); + } + if(!authorized) { + return null; + } for (OsMoSender s : listSenders) { - String l = s.nextSendCommand(); + String l = s.nextSendCommand(this); if (l != null) { StringBuilder res = prepareCommand(l); - pendingSendCommand = ByteBuffer.wrap(res.toString().getBytes("UTF-8")); - break; + return ByteBuffer.wrap(res.toString().getBytes("UTF-8")); } } + return null; } private StringBuilder prepareCommand(String l) { @@ -270,4 +346,4 @@ public class OsMoThread { } return res; } -} \ No newline at end of file +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index ce16b4f0a8..c96680c987 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -13,7 +13,7 @@ public class OsMoTracker implements OsMoSender { } @Override - public String nextSendCommand() { + public String nextSendCommand(OsMoThread thread) { if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|"); diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java index bc0060a2b8..14a4f1f905 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java @@ -1,33 +1,50 @@ package net.osmand.plus.osmo; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; +import android.app.ProgressDialog; +import android.os.AsyncTask; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceScreen; -import android.provider.Settings; +import android.widget.ProgressBar; public class SettingsOsMoActivity extends SettingsBaseActivity { public static final String MORE_VALUE = "MORE_VALUE"; public static final String DEFINE_EDIT = "DEFINE_EDIT"; + private Preference uuid; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getSupportActionBar().setTitle(R.string.online_map_settings); + getSupportActionBar().setTitle(R.string.osmo_settings); PreferenceScreen grp = getPreferenceScreen(); - Preference pref = new Preference(this); - pref.setTitle(R.string.osmo_settings_uuid); - pref.setSummary(OsMoPlugin.getUUID(this)); + uuid = new Preference(this); + uuid.setTitle(R.string.osmo_settings_uuid); + uuid.setSummary(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()); - grp.addPreference(pref); + grp.addPreference(uuid); } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (preference == uuid) { + OsMoPlugin.getEnabledPlugin(OsMoPlugin.class).getRegisterDeviceTask(this, new Runnable() { + @Override + public void run() { + updateAllSettings(); + } + }).execute(); + } + return super.onPreferenceClick(preference); + } public void updateAllSettings() { From 04a2acf5a116083e989773709a87c21c2da94753 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Fri, 16 May 2014 02:11:01 +0300 Subject: [PATCH 02/17] Fix authorization osmo --- OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java | 8 ++++---- OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index 20272e4eba..e134fcdf2e 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -100,6 +100,9 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer }; @Override protected void onPostExecute(Exception result) { + if(dlg.isShowing()) { + dlg.dismiss(); + } if (result != null) { result.printStackTrace(); app.showToastMessage(app.getString(R.string.osmo_io_error) + result.getMessage()); @@ -110,10 +113,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer @Override protected Exception doInBackground(Void... params) { - if(dlg.isShowing()) { - dlg.dismiss(); - } - return OsmandPlugin.getEnabledPlugin(OsMoPlugin.class).registerOsmoDeviceKey(); + return registerOsmoDeviceKey(); } }; } diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java index 14a4f1f905..df82665b69 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java @@ -27,6 +27,7 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { uuid = new Preference(this); uuid.setTitle(R.string.osmo_settings_uuid); uuid.setSummary(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()); + uuid.setOnPreferenceClickListener(this); grp.addPreference(uuid); @@ -39,9 +40,11 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { OsMoPlugin.getEnabledPlugin(OsMoPlugin.class).getRegisterDeviceTask(this, new Runnable() { @Override public void run() { - updateAllSettings(); + updateAllSettings(); + uuid.setSummary(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()); } }).execute(); + return true; } return super.onPreferenceClick(preference); } From 656939390d72b1e13e65409b64e2c04f564bfe73 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Fri, 16 May 2014 13:34:13 +0300 Subject: [PATCH 03/17] Service --- .../src/net/osmand/plus/osmo/OsMoPlugin.java | 62 +--------- .../src/net/osmand/plus/osmo/OsMoService.java | 115 +++++++++++++++++- .../src/net/osmand/plus/osmo/OsMoThread.java | 85 ++++++------- .../src/net/osmand/plus/osmo/OsMoTracker.java | 7 +- 4 files changed, 159 insertions(+), 110 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index e134fcdf2e..b805a3419d 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -1,55 +1,29 @@ package net.osmand.plus.osmo; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - import net.osmand.Location; -import net.osmand.PlatformUtil; import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; -import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.views.MonitoringInfoControl; import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices; import net.osmand.plus.views.OsmandMapTileView; - -import org.apache.commons.logging.Log; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.json.JSONException; -import org.json.JSONObject; - -import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; -import android.os.Build; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; -import android.provider.Settings.Secure; public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices { private OsmandApplication app; public static final String ID = "osmand.osmo"; - private static final Log log = PlatformUtil.getLog(OsMoPlugin.class); private OsMoService service; private OsMoTracker tracker; @@ -113,45 +87,11 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer @Override protected Exception doInBackground(Void... params) { - return registerOsmoDeviceKey(); + return service.registerOsmoDeviceKey(); } }; } - private Exception registerOsmoDeviceKey() { - HttpClient httpclient = new DefaultHttpClient(); - HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); - try { - // Add your data - List nameValuePairs = new ArrayList(2); - nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); - nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); - nameValuePairs.add(new BasicNameValuePair("imei", "0")); - nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); - nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); - httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); - - // Execute HTTP Post Request - HttpResponse response = httpclient.execute(httppost); - InputStream cm = response.getEntity().getContent(); - BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); - String r = reader.readLine(); - reader.close(); - log.info("Authorization key : " + r); - final JSONObject obj = new JSONObject(r); - if(obj.has("error")) { - return new RuntimeException(obj.getString("error")); - } - app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); - return null; - } catch (ClientProtocolException e) { - return e; - } catch (IOException e) { - return e; - } catch (JSONException e) { - return e; - } - } @Override diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 8abe32501a..1850e37bc1 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -1,16 +1,38 @@ package net.osmand.plus.osmo; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONException; import org.json.JSONObject; +import android.os.Build; +import android.provider.Settings.Secure; + +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.Version; public class OsMoService { private OsMoThread thread; private List listSenders = new java.util.concurrent.CopyOnWriteArrayList(); private List listReactors = new java.util.concurrent.CopyOnWriteArrayList(); private OsmandApplication app; + private static final Log log = PlatformUtil.getLog(OsMoService.class); public interface OsMoSender { @@ -38,7 +60,7 @@ public class OsMoService { } thread.stopConnection(); } - thread = new OsMoThread(app, listSenders, listReactors); + thread = new OsMoThread(this, listSenders, listReactors); return true; } @@ -69,4 +91,95 @@ public class OsMoService { } + public Exception registerOsmoDeviceKey() { + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID)); + nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL)); + nameValuePairs.add(new BasicNameValuePair("imei", "0")); + nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT)); + nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app))); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + return new RuntimeException(obj.getString("error")); + } + app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); + return null; + } catch (ClientProtocolException e) { + return e; + } catch (IOException e) { + return e; + } catch (JSONException e) { + return e; + } + } + + public static class SessionInfo { + public String hostName; + public String port; + public String token; + } + + + public SessionInfo getSessionToken() throws IOException { + String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get(); + HttpClient httpclient = new DefaultHttpClient(); + HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare"); + try { + // Add your data + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("key", deviceKey)); + nameValuePairs.add(new BasicNameValuePair("protocol", "1")); + httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + // Execute HTTP Post Request + HttpResponse response = httpclient.execute(httppost); + InputStream cm = response.getEntity().getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(cm)); + String r = reader.readLine(); + reader.close(); + log.info("Authorization key : " + r); + final JSONObject obj = new JSONObject(r); + if(obj.has("error")) { + throw new RuntimeException(obj.getString("error")); + } + if(!obj.has("port")) { + throw new RuntimeException("Port not specified"); + } + if(!obj.has("address")) { + throw new RuntimeException("Host name not specified"); + } + if(!obj.has("token")) { + throw new RuntimeException("Token not specified"); + } + SessionInfo si = new SessionInfo(); + si.hostName = obj.getString("address"); + si.port = obj.getString("port"); + si.token = obj.getString("token"); + return si; + } catch (ClientProtocolException e) { + throw new IOException(e); + } catch (IOException e) { + throw e; + } catch (JSONException e) { + throw new IOException(e); + } + } + + public void showErrorMessage(String string) { + app.showToastMessage(app.getString(R.string.osmo_io_error) + string); + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index 76777bc432..b5feb85ac7 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -13,13 +13,11 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.TreeMap; import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; import net.osmand.plus.osmo.OsMoService.OsMoReactor; import net.osmand.plus.osmo.OsMoService.OsMoSender; +import net.osmand.plus.osmo.OsMoService.SessionInfo; import org.apache.commons.logging.Log; import org.json.JSONException; @@ -28,25 +26,21 @@ import org.json.JSONObject; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; -import android.provider.Settings.Secure; public class OsMoThread { - private static String TRACKER_SERVER = "srv.osmo.mobi"; - private static int TRACKER_PORT = 4242; +// private static String TRACKER_SERVER = "srv.osmo.mobi"; +// private static int TRACKER_PORT = 3245; protected final static Log log = PlatformUtil.getLog(OsMoThread.class); private static final long HEARTBEAT_DELAY = 100; private static final long HEARTBEAT_FAILED_DELAY = 10000; private static final long LIMIT_OF_FAILURES_RECONNECT = 10; - private static final long CONNECTION_DELAY = 25000; private static final long SELECT_TIMEOUT = 500; private static int HEARTBEAT_MSG = 3; private Handler serviceThread; private int failures = 0; private int activeConnectionId = 0; - // -1 means connected, 0 needs to reconnect, > 0 when connection initiated - private long connectionStarted = 0; private boolean stopThread; private Selector selector; @@ -54,7 +48,8 @@ public class OsMoThread { private List listReactors; private boolean authorized; - private OsmandApplication ctx; + private OsMoService service; + private SessionInfo token = null; private String authorizationCommand = null; private SocketChannel activeChannel; private ByteBuffer pendingSendCommand; @@ -62,9 +57,10 @@ public class OsMoThread { private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048); private LinkedList queueOfMessages = new LinkedList(); + - public OsMoThread(OsmandApplication ctx, List listSenders, List listReactors) { - this.ctx = ctx; + public OsMoThread(OsMoService service, List listSenders, List listReactors) { + this.service = service; this.listSenders = listSenders; this.listReactors = listReactors; // start thread to receive events from OSMO @@ -90,19 +86,22 @@ public class OsMoThread { } protected void initConnection() throws IOException { - try { - authorized = false; - authorizationCommand = getAuthorizationCmd(); - selector = Selector.open(); - connectionStarted = System.currentTimeMillis(); - activeChannel = SocketChannel.open(); - activeChannel.configureBlocking(false); - SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); - key.attach(new Integer(++activeConnectionId)); - activeChannel.connect(new InetSocketAddress(TRACKER_SERVER, TRACKER_PORT)); - } catch (IOException e) { - throw e; + if (token == null) { + token = service.getSessionToken(); } + authorized = false; + selector = Selector.open(); + SocketChannel activeChannel = SocketChannel.open(); + activeChannel.configureBlocking(true); + activeChannel.connect(new InetSocketAddress(token.hostName, Integer.parseInt(token.port))); + activeChannel.configureBlocking(false); + SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); + if (this.activeChannel != null) { + stopChannel(); + } + this.activeChannel = activeChannel; + key.attach(new Integer(++activeConnectionId)); + } public String format(String cmd, Map params) { @@ -120,13 +119,6 @@ public class OsMoThread { } } - private String getAuthorizationCmd() { - Map params = new TreeMap(); - params.put("protocol_version", 1); - params.put("key", ctx.getSettings().OSMO_DEVICE_KEY.get()); - return format("AUTH", params); - } - public void scheduleHeartbeat(long delay) { Message msg = serviceThread.obtainMessage(); msg.what = HEARTBEAT_MSG; @@ -139,7 +131,7 @@ public class OsMoThread { } public boolean isConnected() { - return connectionStarted == -1; + return activeChannel != null; } protected void checkAsyncSocket() { @@ -148,12 +140,7 @@ public class OsMoThread { if (selector == null) { stopThread = true; } else { - if (activeChannel != null && connectionStarted != -1 && !activeChannel.isConnectionPending()) { - // connection ready - connectionStarted = -1; - } - if ((connectionStarted != -1 && System.currentTimeMillis() - connectionStarted > CONNECTION_DELAY) - || activeChannel == null) { + if(activeChannel == null) { initConnection(); } else { checkSelectedKeys(); @@ -265,16 +252,20 @@ public class OsMoThread { e.printStackTrace(); } } - if(cmd.equalsIgnoreCase("AUTH")) { - if(obj != null && !obj.has("error")) { - try { - ctx.showToastMessage(ctx.getString(R.string.osmo_io_error) + obj.getString("error")); - } catch (JSONException e) { - e.printStackTrace(); - } - } else { + boolean error = false; + if(obj != null && !obj.has("error")) { + error = true; + try { + service.showErrorMessage(obj.getString("error")); + } catch (JSONException e) { + e.printStackTrace(); + } + } + if(cmd.equalsIgnoreCase("TOKEN")) { + if(!error){ authorized = true; - ctx.showToastMessage("OSMo authorization successfull"); + // TODO delete + service.showErrorMessage("OSMo authorization successfull"); } continue; } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index c96680c987..25078a0d27 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -6,7 +6,8 @@ import net.osmand.Location; import net.osmand.plus.osmo.OsMoService.OsMoSender; public class OsMoTracker implements OsMoSender { - private LinkedList bufferOfLocations = new LinkedList(); + private LinkedList bufferOfLocations = new LinkedList(); + private boolean start; public OsMoTracker(OsMoService service) { service.registerSender(this); @@ -14,6 +15,10 @@ public class OsMoTracker implements OsMoSender { @Override public String nextSendCommand(OsMoThread thread) { + if(!start) { + start = true; + return "TRACKER_SESSION_OPEN"; + } if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|"); From 589eaf7ae281c66f9dcce111a2802241d8b48e9e Mon Sep 17 00:00:00 2001 From: Areg Date: Fri, 16 May 2014 12:32:06 +0100 Subject: [PATCH 04/17] Update SettingsGeneralActivity.java Reverted back the Unit changes so it will be possible to select it independendtly from Driving region: https://code.google.com/p/osmand/issues/detail?id=2317 https://groups.google.com/forum/#!topic/osmand/9P6FclWSyw8 --- .../plus/activities/SettingsGeneralActivity.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java index 6f518c4709..ca687395f1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java @@ -138,16 +138,16 @@ public class SettingsGeneralActivity extends SettingsBaseActivity { DrivingRegion[] drs = DrivingRegion.values(); entries = new String[drs.length]; for (int i = 0; i < entries.length; i++) { - entries[i] = getString(drs[i].name) + " (" + drs[i].defMetrics.toHumanString(this) +")" ; + entries[i] = getString(drs[i].name); // + " (" + drs[i].defMetrics.toHumanString(this) +")" ; } registerListPreference(settings.DRIVING_REGION, screen, entries, drs); -// MetricsConstants[] mvls = MetricsConstants.values(); -// entries = new String[mvls.length]; -// for(int i=0; i Date: Fri, 16 May 2014 20:26:00 +0200 Subject: [PATCH 05/17] share favourites via intent --- OsmAnd/res/values/strings.xml | 2 + .../net/osmand/plus/FavouritesDbHelper.java | 9 +- .../plus/activities/FavouritesActivity.java | 135 +++++++++++------- 3 files changed, 93 insertions(+), 53 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 347b324f54..2b256ca033 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -1441,6 +1441,8 @@ Afghanistan, Albania, Algeria, Andorra, Angola, Anguilla, Antigua and Barbuda, A No favorite points to save Import Export + Share + Favourites shared via OsmAnd Error occurred while loading GPX Send report No offline data for regions found on SD card. Download regions from the Internet. diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index a0ce8ab24b..7f8ed4af28 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -89,6 +89,11 @@ public class FavouritesDbHelper { public String exportFavorites(String fileName) { File f = new File(context.getAppPath(null), fileName); + GPXFile gpx = asGpxFile(); + return GPXUtilities.writeGpxFile(f, gpx, context); + } + + public GPXFile asGpxFile() { GPXFile gpx = new GPXFile(); for (FavouritePoint p : getFavouritePoints()) { if (p.isStored()) { @@ -101,9 +106,9 @@ public class FavouritesDbHelper { gpx.points.add(pt); } } - return GPXUtilities.writeGpxFile(f, gpx, context); + return gpx; } - + private void createCategories(SQLiteConnection db){ addCategoryQuery(context.getString(R.string.favorite_home_category), db); addCategoryQuery(context.getString(R.string.favorite_friends_category), db); diff --git a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java index 25f85ecc44..a01357d70a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavouritesActivity.java @@ -1,5 +1,5 @@ /** - * + * */ package net.osmand.plus.activities; @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import android.content.Intent; import net.londatiga.android.ActionItem; import net.londatiga.android.QuickAction; import net.osmand.access.AccessibleToast; @@ -57,30 +58,26 @@ import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.Window; /** - * + * */ public class FavouritesActivity extends OsmandExpandableListActivity { - public static final int SHOW_ON_MAP = 0; - public static final int NAVIGATE_TO = 1; - public static final int DELETE_ITEM = 2; - public static final int EDIT_ITEM = 3; - public static final int EXPORT_ID = 0; public static final int IMPORT_ID = 1; public static final int DELETE_ID = 2; public static final int DELETE_ACTION_ID = 3; - + public static final int SHARE_ID = 4; + private FavouritesAdapter favouritesAdapter; private FavouritesDbHelper helper; - + private boolean selectionMode = false; private Set favoritesToDelete = new LinkedHashSet(); private Set groupsToDelete = new LinkedHashSet(); private Comparator favoritesComparator; private ActionMode actionMode; - + @Override public void onCreate(Bundle icicle) { @@ -100,18 +97,18 @@ public class FavouritesActivity extends OsmandExpandableListActivity { }; - + setContentView(R.layout.favourites_list); getSupportActionBar().setTitle(R.string.favourites_activity); setSupportProgressBarIndeterminateVisibility(false); // getSupportActionBar().setIcon(R.drawable.tab_search_favorites_icon); - - + + helper = getMyApplication().getFavorites(); favouritesAdapter = new FavouritesAdapter(); favouritesAdapter.setFavoriteGroups(helper.getFavoriteGroups()); getExpandableListView().setAdapter(favouritesAdapter); - + } private void deleteFavorites() { @@ -126,8 +123,8 @@ public class FavouritesActivity extends OsmandExpandableListActivity { hideProgressBar(); favouritesAdapter.synchronizeGroups(); favouritesAdapter.sort(favoritesComparator); - }; - + } + @Override protected void onProgressUpdate(Object... values) { for(Object o : values){ @@ -137,8 +134,8 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favouritesAdapter.deleteCategory((String) o); } } - }; - + } + @Override protected String doInBackground(Void... params) { for (FavouritePoint fp : favoritesToDelete) { @@ -153,20 +150,20 @@ public class FavouritesActivity extends OsmandExpandableListActivity { groupsToDelete.clear(); return getString(R.string.favourites_delete_multiple_succesful); } - + }.execute(); - + } - + @Override protected void onResume() { super.onResume(); // final LatLon mapLocation = getMyApplication().getSettings().getLastKnownMapLocation(); favouritesAdapter.synchronizeGroups(); - + // Sort Favs by distance on Search tab, but sort alphabetically here favouritesAdapter.sort(favoritesComparator); - + } @Override @@ -189,10 +186,10 @@ public class FavouritesActivity extends OsmandExpandableListActivity { OnClickListener onshow = new OnClickListener() { @Override public void onClick(View v) { - settings.SHOW_FAVORITES.set(true); + settings.SHOW_FAVORITES.set(true); } }; - MapActivityActions.createDirectionsActions(qa, location, point, name, settings.getLastKnownMapZoom(), this, + MapActivityActions.createDirectionsActions(qa, location, point, name, settings.getLastKnownMapZoom(), this, true, onshow, false); if (point.isStored()) { ActionItem edit = new ActionItem(); @@ -219,12 +216,12 @@ public class FavouritesActivity extends OsmandExpandableListActivity { }); qa.addActionItem(delete); } - + qa.show(); } return true; } - + private boolean editPoint(final FavouritePoint point) { Builder builder = new AlertDialog.Builder(this); @@ -276,7 +273,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { builder.create().show(); return true; } - + @Override public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item) { if (item.getItemId() == EXPORT_ID) { @@ -285,6 +282,9 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } else if (item.getItemId() == IMPORT_ID) { importFile(); return true; + } else if (item.getItemId() == SHARE_ID) { + shareFavourites(); + return true; } else if (item.getItemId() == DELETE_ID) { enterDeleteMode(); return true; @@ -295,31 +295,33 @@ public class FavouritesActivity extends OsmandExpandableListActivity { return super.onOptionsItemSelected(item); } } - - + + @Override public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { createMenuItem(menu, EXPORT_ID, R.string.export_fav, R.drawable.ic_action_gsave_light, R.drawable.ic_action_gsave_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + createMenuItem(menu, SHARE_ID, R.string.share_fav, R.drawable.ic_action_gshare_light, R.drawable.ic_action_gshare_dark, + MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); createMenuItem(menu, IMPORT_ID, R.string.import_fav, R.drawable.ic_action_grefresh_light, R.drawable.ic_action_grefresh_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); createMenuItem(menu, DELETE_ID, R.string.default_buttons_delete, R.drawable.ic_action_delete_light, R.drawable.ic_action_delete_dark, MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT) ; return super.onCreateOptionsMenu(menu); } - + public void showProgressBar(){ setSupportProgressBarIndeterminateVisibility(true); } - + public void hideProgressBar(){ setSupportProgressBarIndeterminateVisibility(false); } - + private void enterDeleteMode() { actionMode = startActionMode(new Callback() { - + @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { selectionMode = true; @@ -330,18 +332,18 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favouritesAdapter.notifyDataSetInvalidated(); return true; } - + @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } - + @Override public void onDestroyActionMode(ActionMode mode) { selectionMode = false; favouritesAdapter.notifyDataSetInvalidated(); } - + @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if(item.getItemId() == DELETE_ACTION_ID) { @@ -350,11 +352,11 @@ public class FavouritesActivity extends OsmandExpandableListActivity { return true; } - + }); - + } - + private void deleteFavoritesAction() { if (groupsToDelete.size() + favoritesToDelete.size() > 0) { @@ -444,6 +446,37 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } } + private void shareFavourites() { + if (favouritesAdapter.isEmpty()) { + AccessibleToast.makeText(this, R.string.no_fav_to_save, Toast.LENGTH_LONG).show(); + } else { + final AsyncTask exportTask = new AsyncTask() { + @Override + protected GPXFile doInBackground(Void... params) { + return helper.asGpxFile(); + } + + @Override + protected void onPreExecute() { + showProgressBar(); + } + + @Override + protected void onPostExecute(GPXFile gpxFile) { + hideProgressBar(); + final Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, GPXUtilities.asString(gpxFile, getMyApplication())); + sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject)); + sendIntent.setType("application/gpx+xml"); + startActivity(sendIntent); + } + }; + + exportTask.execute(); + } + } + private void export() { final File tosave = getMyApplication().getAppPath(FavouritesDbHelper.FILE_TO_SAVE); if (favouritesAdapter.isEmpty()) { @@ -491,19 +524,19 @@ public class FavouritesActivity extends OsmandExpandableListActivity { } } } - + class FavouritesAdapter extends OsmandBaseExpandableListAdapter { Map> sourceFavoriteGroups; Map> favoriteGroups = new LinkedHashMap>(); List groups = new ArrayList(); - + public void setFavoriteGroups(Map> favoriteGroups) { this.sourceFavoriteGroups = favoriteGroups; synchronizeGroups(); } - + public void sort(Comparator comparator) { for(List ps : favoriteGroups.values()) { Collections.sort(ps, comparator); @@ -518,14 +551,14 @@ public class FavouritesActivity extends OsmandExpandableListActivity { favoriteGroups.get(p.getCategory()).add(p); notifyDataSetChanged(); } - + public void deleteFavoritePoint(FavouritePoint p) { if(favoriteGroups.containsKey(p.getCategory())){ favoriteGroups.get(p.getCategory()).remove(p); } notifyDataSetChanged(); } - + public void deleteCategory(String p) { favoriteGroups.remove(p); groups.remove(p); @@ -582,7 +615,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } - + @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View row = convertView; @@ -596,11 +629,11 @@ public class FavouritesActivity extends OsmandExpandableListActivity { final String model = getGroup(groupPosition); label.setText(model); final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item); - + if(selectionMode){ ch.setVisibility(View.VISIBLE); ch.setChecked(groupsToDelete.contains(model)); - + ch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -629,7 +662,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { LayoutInflater inflater = getLayoutInflater(); row = inflater.inflate(R.layout.favourites_list_item, parent, false); } - + TextView label = (TextView) row.findViewById(R.id.favourite_label); ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon); final FavouritePoint model = (FavouritePoint) getChild(groupPosition, childPosition); @@ -640,7 +673,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { icon.setImageResource(R.drawable.opened_poi); } LatLon lastKnownMapLocation = getMyApplication().getSettings().getLastKnownMapLocation(); - int dist = (int) (MapUtils.getDistance(model.getLatitude(), model.getLongitude(), + int dist = (int) (MapUtils.getDistance(model.getLatitude(), model.getLongitude(), lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude())); String distance = OsmAndFormatter.getFormattedDistance(dist, getMyApplication()) + " "; label.setText(distance + model.getName(), TextView.BufferType.SPANNABLE); @@ -651,7 +684,7 @@ public class FavouritesActivity extends OsmandExpandableListActivity { ch.setChecked(favoritesToDelete.contains(model)); row.findViewById(R.id.favourite_icon).setVisibility(View.GONE); ch.setOnClickListener(new View.OnClickListener() { - + @Override public void onClick(View v) { if(ch.isChecked()){ From cd790c9978a0dba306ed0feb259557b58bdcb449 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Fri, 16 May 2014 17:19:19 +0300 Subject: [PATCH 06/17] Save current tab --- .../src/net/osmand/plus/OsmandSettings.java | 4 ++++ .../activities/search/SearchActivity.java | 23 +++++++------------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 5d650faf49..2b6b04cfa1 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -1661,6 +1661,10 @@ public class OsmandSettings { public static final int OSMAND_DARK_THEME = 0; public static final int OSMAND_LIGHT_THEME = 1; public static final int OSMAND_LIGHT_DARK_ACTIONBAR_THEME = 2; + + public final CommonPreference SEARCH_TAB = + new IntPreference("SEARCH_TAB", 0).makeGlobal().cache(); + public final CommonPreference OSMAND_THEME = new IntPreference("osmand_theme", OSMAND_DARK_THEME).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java index bdad87c05b..3af7ee39c1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java @@ -56,8 +56,6 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo public static final int HISTORY_TAB_INDEX = 3; public static final int TRANSPORT_TAB_INDEX = 4; - public static final String TAB_INDEX_EXTRA = "TAB_INDEX_EXTRA"; - protected static final int POSITION_CURRENT_LOCATION = 1; protected static final int POSITION_LAST_MAP_VIEW = 2; protected static final int POSITION_FAVORITES = 3; @@ -106,6 +104,7 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); setContentView(R.layout.search_main); settings = ((OsmandApplication) getApplication()).getSettings(); + Integer tab = settings.SEARCH_TAB.get(); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle(""); // getSupportActionBar().setTitle(R.string.select_search_position); @@ -119,7 +118,7 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo tabHost.setup(); ViewPager mViewPager = (ViewPager)findViewById(R.id.pager); - mTabsAdapter = new TabsAdapter(this, tabHost, tabinfo, mViewPager); + mTabsAdapter = new TabsAdapter(this, tabHost, tabinfo, mViewPager, settings); TabSpec poiTab = tabHost.newTabSpec(SEARCH_POI).setIndicator(getTabIndicator(tabHost, R.drawable.tab_search_poi_icon, R.string.poi)); mTabsAdapter.addTab(poiTab, SearchPoiFilterActivity.class, null); @@ -135,22 +134,15 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo mTabsAdapter.addTab(historyTab, SearchHistoryFragment.class, null); TabSpec transportTab = tabHost.newTabSpec(SEARCH_TRANSPORT).setIndicator(getTabIndicator(tabHost, R.drawable.tab_search_transport_icon, R.string.transport)); mTabsAdapter.addTab(transportTab, SearchTransportFragment.class, null); - tabHost.setCurrentTab(POI_TAB_INDEX); - if (savedInstanceState != null) { - tabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); - } + tabHost.setCurrentTab(tab); setTopSpinner(); Log.i("net.osmand", "Start on create " + (System.currentTimeMillis() - t )); Intent intent = getIntent(); - int tabIndex = 0; + OsmandSettings settings = ((OsmandApplication) getApplication()).getSettings(); if (intent != null) { - if(intent.hasExtra(TAB_INDEX_EXTRA)){ - tabIndex = intent.getIntExtra(TAB_INDEX_EXTRA, POI_TAB_INDEX); - mTabsAdapter.mTabHost.setCurrentTab(tabIndex); - } double lat = intent.getDoubleExtra(SEARCH_LAT, 0); double lon = intent.getDoubleExtra(SEARCH_LON, 0); if (lat != 0 || lon != 0) { @@ -234,7 +226,6 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putString("tab", mTabsAdapter.mTabHost.getCurrentTabTag()); } @@ -358,7 +349,6 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo // mTabsAdapter.notifyDataSetChanged(); // mTabsAdapter.mViewPager.invalidate(); Intent intent = getIntent(); - intent.putExtra(TAB_INDEX_EXTRA, ADDRESS_TAB_INDEX); finish(); startActivity(intent); } @@ -382,6 +372,7 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo private final ViewPager mViewPager; private final ArrayList mTabs = new ArrayList(); private TextView tabInfo; + private OsmandSettings osmSettings; static final class TabInfo { private final String tag; @@ -411,12 +402,13 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo } } - public TabsAdapter(FragmentActivity activity, TabHost tabHost, TextView tabinfo, ViewPager pager) { + public TabsAdapter(FragmentActivity activity, TabHost tabHost, TextView tabinfo, ViewPager pager, OsmandSettings settings) { super(activity.getSupportFragmentManager()); mContext = activity; mTabHost = tabHost; tabInfo = tabinfo; mViewPager = pager; + osmSettings = settings; mTabHost.setOnTabChangedListener(this); mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); @@ -447,6 +439,7 @@ public class SearchActivity extends SherlockFragmentActivity implements OsmAndLo @Override public void onTabChanged(String tabId) { int position = mTabHost.getCurrentTab(); + osmSettings.SEARCH_TAB.set(position); mViewPager.setCurrentItem(position); if (SEARCH_POI.equals(tabId)) { tabInfo.setText(R.string.poi_search_desc); From 08fc05761047f6219c85d23160b138dddb852da6 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sat, 17 May 2014 01:58:00 +0300 Subject: [PATCH 07/17] Current tracker --- .../src/net/osmand/plus/osmo/OsMoService.java | 6 +- .../src/net/osmand/plus/osmo/OsMoTracker.java | 108 ++++++++++++++++-- 2 files changed, 105 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 1850e37bc1..b16dbc08de 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -165,8 +165,10 @@ public class OsMoService { throw new RuntimeException("Token not specified"); } SessionInfo si = new SessionInfo(); - si.hostName = obj.getString("address"); - si.port = obj.getString("port"); + String a = obj.getString("address"); + int i = a.indexOf(':'); + si.hostName = a.substring(0, i); + si.port = a.substring(i + 1); si.token = obj.getString("token"); return si; } catch (ClientProtocolException e) { diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index 25078a0d27..f55790e980 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -1,23 +1,60 @@ package net.osmand.plus.osmo; -import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import net.osmand.Location; +import net.osmand.plus.osmo.OsMoService.OsMoReactor; import net.osmand.plus.osmo.OsMoService.OsMoSender; +import net.osmand.plus.views.OsmandMapTileView; -public class OsMoTracker implements OsMoSender { - private LinkedList bufferOfLocations = new LinkedList(); - private boolean start; +import org.json.JSONObject; + +public class OsMoTracker implements OsMoSender, OsMoReactor { + private ConcurrentLinkedQueue bufferOfLocations = new ConcurrentLinkedQueue(); + private Map otherLocations = new ConcurrentHashMap(); + private ConcurrentLinkedQueue listenIds = new ConcurrentLinkedQueue(); + private boolean trackerStarted; + private boolean startSendingLocations; + private OsmandMapTileView view; public OsMoTracker(OsMoService service) { service.registerSender(this); + service.registerReactor(this); + } + + public void enableTracker() { + startSendingLocations = true; + } + + public void disableTracker() { + startSendingLocations = false; + } + + public void startTrackingId(String id) { + listenIds.add("LISTEN|"+id); + otherLocations.put(id, null); + } + + public void stopTrackingId(String id) { + listenIds.add("UNLISTEN|"+id); + otherLocations.remove(id); } @Override public String nextSendCommand(OsMoThread thread) { - if(!start) { - start = true; - return "TRACKER_SESSION_OPEN"; + if (trackerStarted != startSendingLocations) { + if (!trackerStarted) { + trackerStarted = true; + return "TRACKER_SESSION_OPEN"; + } else { + trackerStarted = false; + return "TRACKER_SESSION_CLOSE"; + } + } + if(!listenIds.isEmpty()) { + return listenIds.poll(); } if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); @@ -32,6 +69,12 @@ public class OsMoTracker implements OsMoSender { if(loc.hasSpeed()) { cmd.append("S").append((float)loc.getSpeed()); } + if(loc.hasBearing()) { + cmd.append("C").append((float)loc.getBearing()); + } + if((System.currentTimeMillis() - loc.getTime()) > 30000) { + cmd.append("T").append(loc.getTime()); + } return cmd.toString(); } return null; @@ -48,5 +91,56 @@ public class OsMoTracker implements OsMoSender { bufferOfLocations.add(l); } + public void setView(OsmandMapTileView view) { + this.view = view; + } + + public OsmandMapTileView getView() { + return view; + } + + @Override + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) { + if(command.startsWith("LT:")) { + String tid = command.substring(3); + float lat = 0; + float lon = 0; + float speed = 0; + int k = 0; + for (int i = 0; i <= data.length(); i++) { + boolean separator = i == data.length() || Character.isDigit(data.charAt(i)) || data.charAt(i) == ':' + || data.charAt(i) == '.'; + if (separator) { + char ch = data.charAt(k); + String vl = data.substring(k + 1, i); + if (ch == 'L') { + int l = vl.indexOf(":"); + lat = Float.parseFloat(vl.substring(0, l)); + lon = Float.parseFloat(vl.substring(l + 1)); + } else if (ch == 'S') { + speed = Float.parseFloat(vl); + } + k = i; + } + } + if(lat != 0 || lon != 0) { + Location loc = new Location("osmo"); + loc.setTime(System.currentTimeMillis()); + loc.setLatitude(lat); + loc.setLongitude(lon); + if(speed > 0) { + loc.setSpeed(speed); + } + otherLocations.put(tid, loc); + OsmandMapTileView v = view; + if(v != null){ + v.refreshMap(); + } + } + return true; + } + return false; + } + } From 62ddbcb124518341496dda7228a3da7268014d70 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sat, 17 May 2014 02:02:18 +0300 Subject: [PATCH 08/17] fix build --- .../net/osmand/plus/activities/SettingsGeneralActivity.java | 1 + OsmAnd/src/net/osmand/plus/osmo/OsMoService.java | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java index ca687395f1..c70c293b6a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java @@ -17,6 +17,7 @@ import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.DrivingRegion; +import net.osmand.plus.OsmandSettings.MetricsConstants; import net.osmand.plus.ProgressDialogImplementation; import net.osmand.plus.R; import net.osmand.plus.Version; diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index b16dbc08de..1cddf9af82 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -155,9 +155,6 @@ public class OsMoService { if(obj.has("error")) { throw new RuntimeException(obj.getString("error")); } - if(!obj.has("port")) { - throw new RuntimeException("Port not specified"); - } if(!obj.has("address")) { throw new RuntimeException("Host name not specified"); } From 8c88a19d4b70eec64aac5a0cfe5dad8b2010ebc6 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sat, 17 May 2014 02:40:15 +0300 Subject: [PATCH 09/17] Fix small issues --- .../src/net/osmand/plus/osmo/OsMoThread.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index b5feb85ac7..1dbc5d49a2 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -47,10 +47,9 @@ public class OsMoThread { private List listSenders; private List listReactors; - private boolean authorized; + private int authorized = 0; // 1 - send, 2 - authorized private OsMoService service; private SessionInfo token = null; - private String authorizationCommand = null; private SocketChannel activeChannel; private ByteBuffer pendingSendCommand; private String readCommand = ""; @@ -89,7 +88,7 @@ public class OsMoThread { if (token == null) { token = service.getSessionToken(); } - authorized = false; + authorized = 0; selector = Selector.open(); SocketChannel activeChannel = SocketChannel.open(); activeChannel.configureBlocking(true); @@ -210,7 +209,7 @@ public class OsMoThread { while (hasSomethingToRead) { pendingReadCommand.clear(); int read = activeChannel.read(pendingReadCommand); - if (pendingReadCommand.hasRemaining()) { + if (!pendingReadCommand.hasRemaining()) { hasSomethingToRead = true; } else { hasSomethingToRead = false; @@ -256,14 +255,14 @@ public class OsMoThread { if(obj != null && !obj.has("error")) { error = true; try { - service.showErrorMessage(obj.getString("error")); + service.showErrorMessage(obj.getString("description")); } catch (JSONException e) { e.printStackTrace(); } } - if(cmd.equalsIgnoreCase("TOKEN")) { + if(header.equalsIgnoreCase("TOKEN")) { if(!error){ - authorized = true; + authorized = 2; // TODO delete service.showErrorMessage("OSMo authorization successfull"); } @@ -290,17 +289,18 @@ public class OsMoThread { activeChannel.write(pendingSendCommand); if (!pendingSendCommand.hasRemaining()) { pendingSendCommand = getNewPendingSendCommand(); + } else { + break; } } } private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException { - if(authorizationCommand != null) { - String auth = authorizationCommand; - authorizationCommand = null; + if(authorized == 0) { + String auth = "TOKEN|"+ token.token; return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8")); } - if(!authorized) { + if(authorized == 1) { return null; } for (OsMoSender s : listSenders) { From 2f1668c585083c45a4aabe9477122210152eb689 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sat, 17 May 2014 13:29:37 +0300 Subject: [PATCH 10/17] Fix thread --- OsmAnd/res/xml/general_settings.xml | 6 +++--- OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/xml/general_settings.xml b/OsmAnd/res/xml/general_settings.xml index 021f043585..a504808729 100644 --- a/OsmAnd/res/xml/general_settings.xml +++ b/OsmAnd/res/xml/general_settings.xml @@ -8,9 +8,9 @@ - + + + diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index 1dbc5d49a2..a83596003a 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -252,7 +252,7 @@ public class OsMoThread { } } boolean error = false; - if(obj != null && !obj.has("error")) { + if(obj != null && obj.has("error")) { error = true; try { service.showErrorMessage(obj.getString("description")); From ccaf20c1a0108c6bc37e1d881347e503d10884af Mon Sep 17 00:00:00 2001 From: GiZig Date: Sun, 18 May 2014 03:12:26 +0200 Subject: [PATCH 11/17] Update strings.xml --- OsmAnd/res/values-fr/strings.xml | 42 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 62aa70c0de..71b61ef4dc 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -559,7 +559,7 @@ Rue :\n{0}\n{1} Intersection :\n{0} x {1} dans {2} Bâtiment :\n{0} {1}\n{2} - Favori + Favori Effacer tout Historique Envoi des données… @@ -601,7 +601,7 @@ Ouverture des modifications… Fermeture des modifications… Envoi des nœuds… - Chargement des Points d\'Intérêts… + Chargement des Points d\'intérêts… Autorisation refusée Échec Convertir les noms en anglais… @@ -909,14 +909,14 @@ Privé Récupérer votre véhicule du parking Avertissement - Une notification pour récupérer votre véhicule a été ajoutée dans votre agenda. Elle y restera jusqu\'à ce que vous le supprimiez manuellement. + Une notification pour récupérer votre véhicule a été ajoutée dans votre agenda. Elle y restera jusqu\'à ce que vous la supprimiez manuellement. Donner un temps limite de stationnement Voulez-vous supprimer l\'emplacement de stationnement du véhicule ? Supprimer un emplacement de stationnement Choisir le type de stationnement Temps limité Temps illimité - Ajouter une notification dans l\'Agenda + Ajouter une notification dans l\'agenda Stationnement avec limite de temps Stationnement sans limite de temps La position de votre véhicule. %1$s @@ -1093,7 +1093,7 @@ Aucun numéro de bâtiment trouvé Rechercher les villages et les codes postaux Lat %1$.3f lon %2$.3f - la position actuelle + La position actuelle Limite de vitesse @@ -1281,7 +1281,7 @@ Effacer la destination Autre Il reste %1$d fichiers - Reste %1$d fichiers à télécharger + Vous pouvez encore télécharger %1$d fichier(s). Version complète Utiliser le magnétomètre pour déterminer l\'orientation de la boussole au lieu du capteur d\'orientation Utiliser le magnétomètre (boussole) @@ -1472,10 +1472,10 @@ Éviter les autoroutes Poids Spécifier la limite de poids - Sélectionner GPX … + Sélectionner GPX… Définir la destination - Définir sur la carte … - Favori … + Définir sur la carte… + Favori… Préférences d\'itinéraire Informations sur l\'itinéraire Ajouter comme destination @@ -1551,18 +1551,22 @@ Interrompre la musique lors des annonces Interrompre la musique Partager l\'itinéraire au format GPX - Itinéraire partagé via OsmAnd +Itinéraire partagé via OsmAnd Identifiant unique de l\'appareil - Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi - OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi - OSMo (suivi en temps réel) - OSMo - Jamais - Annoncer les instructions de navigation à intervalles réguliers - Répéter les instructions de navigation - Format invalide : %s + Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi + OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi + OSMo (suivi en temps réel) + OSMo + Enregistrement de l\'appareil… + Problème de connection OSMo : + Arrêter\nOSMo + Démarrer\nOSMo +Jamais +Annoncer les instructions de navigation à intervalles réguliers +Répéter les instructions de navigation +Format invalide : %s Annonce de l\'arrivée - Choisir à quel moment est annoncée l\'arrivée à destination +Choisir à quel moment est annoncée l\'arrivée à destination Précoce Normale From d13d59c445802e4c111437154cae09181724a90a Mon Sep 17 00:00:00 2001 From: vshcherb Date: Sun, 18 May 2014 23:46:54 +0300 Subject: [PATCH 12/17] Add groups API --- .../src/net/osmand/plus/OsmandSettings.java | 2 + .../src/net/osmand/plus/osmo/OsMoGroups.java | 277 ++++++++++++++++++ .../src/net/osmand/plus/osmo/OsMoPlugin.java | 12 + .../src/net/osmand/plus/osmo/OsMoReactor.java | 9 + .../src/net/osmand/plus/osmo/OsMoSender.java | 6 + .../src/net/osmand/plus/osmo/OsMoService.java | 37 ++- .../src/net/osmand/plus/osmo/OsMoThread.java | 13 +- .../src/net/osmand/plus/osmo/OsMoTracker.java | 14 +- 8 files changed, 341 insertions(+), 29 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java create mode 100644 OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java create mode 100644 OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 2b6b04cfa1..b5b5042193 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -826,6 +826,8 @@ public class OsmandSettings { public final OsmandPreference OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal(); + public final OsmandPreference OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal(); + // this value string is synchronized with settings_pref.xml preference name public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference("debug_rendering", false).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java new file mode 100644 index 0000000000..956f6f2682 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java @@ -0,0 +1,277 @@ +package net.osmand.plus.osmo; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import net.osmand.data.LatLon; +import net.osmand.plus.OsmandSettings; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class OsMoGroups implements OsMoReactor { + + private static final String TRACKER_ID = "trackerId"; + private static final String GROUP_TRACKERS = "group_trackers"; + private static final String GROUP_ID = "group_id"; + private static final String NAME = "name"; + private static final String USER_NAME = "userName"; + private static final String GROUP_NAME = "group_name"; + private static final String MY_GROUP_TRACKER_ID = "my_group_tracker_id"; + private OsMoTracker tracker; + private ConcurrentHashMap groups = new ConcurrentHashMap(); + private OsMoGroup mainGroup; + private OsmandSettings settings; + private OsMoService service; + + public static class OsMoGroup { + public String name; + public String userName; + public String groupId; + public String myGroupTrackerId; + public boolean active; + + public Map users = new ConcurrentHashMap(); + + public boolean isMainGroup() { + return groupId == null; + } + + public String getVisibleName(){ + if(userName != null && userName.length() > 0) { + return userName; + } + return name; + } + } + + public static class OsMoMessage { + public long timestamp; + public LatLon location; + public String text; + } + + public static class OsMoUser { + public String serverName; + public String userName; + public String trackerId; + public List messages = new ArrayList(); + + public String getVisibleName(){ + if(userName != null && userName.length() > 0) { + return userName; + } + return serverName; + } + } + + public OsMoGroups(OsMoService service, OsMoTracker tracker, OsmandSettings settings) { + this.service = service; + this.tracker = tracker; + this.settings = settings; +// service.registerSender(this); + service.registerReactor(this); + mainGroup = new OsMoGroup(); + groups.put("", mainGroup); + + parseGroups(); + } + + private void parseGroups() { + String grp = settings.OSMO_GROUPS.get(); + try { + JSONObject obj = new JSONObject(grp); + parseGroupUsers(mainGroup, obj); + JSONArray groups = obj.getJSONArray("groups"); + for (int i = 0; i < groups.length(); i++) { + JSONObject o = (JSONObject) groups.get(i); + OsMoGroup group = new OsMoGroup(); + group.groupId = o.getString(GROUP_ID); + if(o.has(MY_GROUP_TRACKER_ID)) { + group.myGroupTrackerId = o.getString(MY_GROUP_TRACKER_ID); + } + if(o.has(NAME)) { + group.name = o.getString(NAME); + } + if(o.has(USER_NAME)) { + group.userName = o.getString(USER_NAME); + } + parseGroupUsers(group, o); + this.groups.put(group.groupId, group); + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + } + + public void saveGroups() { + JSONObject mainObj = new JSONObject(); + try { + saveGroupUsers(mainGroup, mainObj); + JSONArray ar = new JSONArray(); + for(OsMoGroup gr : groups.values()) { + if(gr.isMainGroup()) { + continue; + } + JSONObject obj = new JSONObject(); + if (gr.userName != null) { + obj.put(USER_NAME, gr.userName); + } + if (gr.name != null) { + obj.put(NAME, gr.name); + } + obj.put(GROUP_ID, gr.groupId); + ar.put(obj); + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + settings.OSMO_GROUPS.set(mainObj.toString()); + } + + private void saveGroupUsers(OsMoGroup gr, JSONObject grObj) throws JSONException { + JSONArray ar = new JSONArray(); + for(OsMoUser u : gr.users.values()) { + JSONObject obj = new JSONObject(); + if (u.userName != null) { + obj.put(USER_NAME, u.userName); + } + if (u.serverName != null) { + obj.put("serverName", u.serverName); + } + obj.put(TRACKER_ID, u.trackerId); + + ar.put(obj); + } + grObj.put("users", ar); + } + + private void parseGroupUsers(OsMoGroup gr, JSONObject obj) throws JSONException { + JSONArray users = obj.getJSONArray("users"); + for (int i = 0; i < users.length(); i++) { + JSONObject o = (JSONObject) users.get(i); + OsMoUser user = new OsMoUser(); + if(o.has("serverName")) { + user.serverName = o.getString("serverName"); + } + if(o.has(USER_NAME)) { + user.userName = o.getString(USER_NAME); + } + user.trackerId = o.getString(TRACKER_ID); + } + } + + @Override + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) { + if(command.startsWith("ON_GROUP_CHANGE:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + mergeGroup(gr, obj, false); + } + return true; + } else if(command.startsWith("CREATE_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = new OsMoGroup(); + gr.groupId = gid; + try { + gr.name = obj.getString(GROUP_NAME); + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + joinGroup(gid); + } else if(command.startsWith("JOIN_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + mergeGroup(gr, obj, true); + gr.active = true; + for(String key : gr.users.keySet()) { + if (!key.equals(gr.myGroupTrackerId)) { + tracker.startTrackingId(key); + } + } + } + return true; + } else if(command.startsWith("LEAVE_GROUP:")) { + String gid = command.substring(command.indexOf(':') + 1); + OsMoGroup gr = groups.get(gid); + if(gr != null) { + gr.active = false; + for(String key : gr.users.keySet()) { + if (!key.equals(gr.myGroupTrackerId)) { + tracker.stopTrackingId(key); + } + } + } + return true; + } + return false; + } + + + private void mergeGroup(OsMoGroup gr, JSONObject obj, boolean deleteUsers) { + try { + if(obj.has(GROUP_NAME)) { + gr.name = obj.getString(GROUP_NAME); + } + if(obj.has(MY_GROUP_TRACKER_ID)) { + gr.myGroupTrackerId = obj.getString(MY_GROUP_TRACKER_ID); + } + JSONArray arr = obj.getJSONArray(GROUP_TRACKERS); + Set toDelete = new HashSet(gr.users.keySet()); + for (int i = 0; i < arr.length(); i++) { + JSONObject o = (JSONObject) arr.get(i); + String tid = o.getString(TRACKER_ID); + toDelete.remove(tid); + OsMoUser us = gr.users.get(tid); + if (us == null) { + us = new OsMoUser(); + us.trackerId = tid; + gr.users.put(tid, us); + if(gr.active) { + if (!tid.equals(gr.myGroupTrackerId)) { + tracker.startTrackingId(tid); + } + } + } + if (o.has(NAME)) { + us.serverName = o.getString(NAME); + } + } + if(deleteUsers) { + for(String s : toDelete) { + gr.users.remove(s); + if(gr.active) { + tracker.stopTrackingId(s); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + service.showErrorMessage(e.getMessage()); + } + } + + public void joinGroup(String groupId) { + service.pushCommand("JOIN_GROUP|"+groupId); + } + + public void createGroup(String groupName) { + service.pushCommand("CREATE_GROUP|{\"group_name\":\"" + groupName + "\"}"); + } + + + public void leaveGroup(OsMoGroup group) { + service.pushCommand("LEAVE_GROUP|"+group.groupId); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index b805a3419d..e2f9b63181 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -26,10 +26,12 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public static final String ID = "osmand.osmo"; private OsMoService service; private OsMoTracker tracker; + private OsMoGroups groups; public OsMoPlugin(final OsmandApplication app) { service = new OsMoService(app); tracker = new OsMoTracker(service); + groups = new OsMoGroups(service, tracker, app.getSettings()); this.app = app; } @@ -155,4 +157,14 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public String getId() { return ID; } + + public OsMoGroups getGroups() { + return groups; + } + + + public OsMoTracker getTracker() { + return tracker; + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java new file mode 100644 index 0000000000..4869b5c03d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java @@ -0,0 +1,9 @@ +package net.osmand.plus.osmo; + +import org.json.JSONObject; + +public interface OsMoReactor { + + public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread tread); + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java new file mode 100644 index 0000000000..3252289c2e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java @@ -0,0 +1,6 @@ +package net.osmand.plus.osmo; + +public interface OsMoSender { + + public String nextSendCommand(OsMoThread tracker); +} diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 1cddf9af82..7476f67727 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -6,6 +6,12 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.Version; import org.apache.commons.logging.Log; import org.apache.http.HttpResponse; @@ -22,31 +28,19 @@ import org.json.JSONObject; import android.os.Build; import android.provider.Settings.Secure; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.Version; - -public class OsMoService { +public class OsMoService implements OsMoSender { private OsMoThread thread; private List listSenders = new java.util.concurrent.CopyOnWriteArrayList(); private List listReactors = new java.util.concurrent.CopyOnWriteArrayList(); + private ConcurrentLinkedQueue commands = new ConcurrentLinkedQueue(); private OsmandApplication app; private static final Log log = PlatformUtil.getLog(OsMoService.class); - public interface OsMoSender { - - public String nextSendCommand(OsMoThread tracker); - } - public interface OsMoReactor { - - public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread tracker); - - } public OsMoService(OsmandApplication app) { this.app = app; + listSenders.add(this); } public boolean isConnected() { @@ -130,6 +124,7 @@ public class OsMoService { public String hostName; public String port; public String token; + } @@ -181,4 +176,16 @@ public class OsMoService { app.showToastMessage(app.getString(R.string.osmo_io_error) + string); } + public void pushCommand(String cmd) { + commands.add(cmd); + } + + @Override + public String nextSendCommand(OsMoThread tracker) { + if(!commands.isEmpty()) { + return commands.poll(); + } + return null; + } + } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index a83596003a..7d0de0649e 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -15,8 +15,6 @@ import java.util.Map.Entry; import java.util.Set; import net.osmand.PlatformUtil; -import net.osmand.plus.osmo.OsMoService.OsMoReactor; -import net.osmand.plus.osmo.OsMoService.OsMoSender; import net.osmand.plus.osmo.OsMoService.SessionInfo; import org.apache.commons.logging.Log; @@ -42,6 +40,7 @@ public class OsMoThread { private int failures = 0; private int activeConnectionId = 0; private boolean stopThread; + private boolean reconnect; private Selector selector; private List listSenders; @@ -57,6 +56,7 @@ public class OsMoThread { private LinkedList queueOfMessages = new LinkedList(); + public OsMoThread(OsMoService service, List listSenders, List listReactors) { this.service = service; @@ -89,6 +89,7 @@ public class OsMoThread { token = service.getSessionToken(); } authorized = 0; + reconnect = false; selector = Selector.open(); SocketChannel activeChannel = SocketChannel.open(); activeChannel.configureBlocking(true); @@ -139,7 +140,7 @@ public class OsMoThread { if (selector == null) { stopThread = true; } else { - if(activeChannel == null) { + if(activeChannel == null || reconnect) { initConnection(); } else { checkSelectedKeys(); @@ -153,7 +154,7 @@ public class OsMoThread { activeChannel = null; } if (failures++ > LIMIT_OF_FAILURES_RECONNECT) { - stopChannel(); + reconnect = true; } } if (stopThread) { @@ -214,7 +215,9 @@ public class OsMoThread { } else { hasSomethingToRead = false; } - if (read > 0) { + if(read == -1) { + reconnect = true; + } else if (read > 0) { byte[] ar = pendingReadCommand.array(); String res = new String(ar, 0, read); readCommand += res; diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index f55790e980..285829faac 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -5,8 +5,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import net.osmand.Location; -import net.osmand.plus.osmo.OsMoService.OsMoReactor; -import net.osmand.plus.osmo.OsMoService.OsMoSender; import net.osmand.plus.views.OsmandMapTileView; import org.json.JSONObject; @@ -14,12 +12,13 @@ import org.json.JSONObject; public class OsMoTracker implements OsMoSender, OsMoReactor { private ConcurrentLinkedQueue bufferOfLocations = new ConcurrentLinkedQueue(); private Map otherLocations = new ConcurrentHashMap(); - private ConcurrentLinkedQueue listenIds = new ConcurrentLinkedQueue(); private boolean trackerStarted; private boolean startSendingLocations; private OsmandMapTileView view; + private OsMoService service; public OsMoTracker(OsMoService service) { + this.service = service; service.registerSender(this); service.registerReactor(this); } @@ -33,12 +32,12 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { } public void startTrackingId(String id) { - listenIds.add("LISTEN|"+id); + service.pushCommand("LISTEN|"+id); otherLocations.put(id, null); } public void stopTrackingId(String id) { - listenIds.add("UNLISTEN|"+id); + service.pushCommand("UNLISTEN|"+id); otherLocations.remove(id); } @@ -53,9 +52,6 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { return "TRACKER_SESSION_CLOSE"; } } - if(!listenIds.isEmpty()) { - return listenIds.poll(); - } if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|"); @@ -102,7 +98,7 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { @Override public boolean acceptCommand(String command, String data, JSONObject obj, OsMoThread thread) { if(command.startsWith("LT:")) { - String tid = command.substring(3); + String tid = command.substring(command.indexOf(':') + 1); float lat = 0; float lon = 0; float speed = 0; From 2d548eec4678299016ef0699da95189035eac9d2 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Mon, 19 May 2014 01:50:17 +0300 Subject: [PATCH 13/17] Fix osmo --- OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java | 1 + OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java | 8 +++++++- OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index e2f9b63181..13f5e213b4 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -31,6 +31,7 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public OsMoPlugin(final OsmandApplication app) { service = new OsMoService(app); tracker = new OsMoTracker(service); + tracker.enableTracker(); groups = new OsMoGroups(service, tracker, app.getSettings()); this.app = app; } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index 7d0de0649e..fc24a6be72 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -239,6 +239,7 @@ public class OsMoThread { private void processReadMessages() { while(!queueOfMessages.isEmpty()){ String cmd = queueOfMessages.poll(); + log.info("OSMO get:"+cmd); int k = cmd.indexOf('|'); String header = cmd; String data = ""; @@ -258,7 +259,7 @@ public class OsMoThread { if(obj != null && obj.has("error")) { error = true; try { - service.showErrorMessage(obj.getString("description")); + service.showErrorMessage(obj.getString("error")); } catch (JSONException e) { e.printStackTrace(); } @@ -297,10 +298,14 @@ public class OsMoThread { } } } + + private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException { if(authorized == 0) { String auth = "TOKEN|"+ token.token; + log.info("OSMO send:" + auth); + authorized = 1; return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8")); } if(authorized == 1) { @@ -310,6 +315,7 @@ public class OsMoThread { String l = s.nextSendCommand(this); if (l != null) { StringBuilder res = prepareCommand(l); + log.info("OSMO send " + res); return ByteBuffer.wrap(res.toString().getBytes("UTF-8")); } } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index 285829faac..1a160367d3 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -68,7 +68,7 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { if(loc.hasBearing()) { cmd.append("C").append((float)loc.getBearing()); } - if((System.currentTimeMillis() - loc.getTime()) > 30000) { + if((System.currentTimeMillis() - loc.getTime()) > 30000 && loc.getTime() != 0) { cmd.append("T").append(loc.getTime()); } return cmd.toString(); @@ -77,7 +77,9 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { } public void sendCoordinate(Location location) { - bufferOfLocations.add(location); + if(startSendingLocations) { + bufferOfLocations.add(location); + } } public void sendCoordinate(double lat, double lon) { From 81daec3e7043e547b78cb90126636868acfb3de3 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Wed, 21 May 2014 01:55:59 +0200 Subject: [PATCH 14/17] Add feature to calculate route between rtept --- OsmAnd/res/values/strings.xml | 1 + OsmAnd/src/net/osmand/plus/GPXUtilities.java | 20 +++++++ .../src/net/osmand/plus/OsmandSettings.java | 7 +-- .../plus/activities/MapActivityActions.java | 12 +++-- .../osmand/plus/base/FailSafeFuntions.java | 9 ++-- .../osmand/plus/routing/RouteProvider.java | 53 ++++++++++++++++--- .../osmand/plus/routing/RoutingHelper.java | 2 +- .../controls/MapRoutePreferencesControl.java | 26 ++++++--- 8 files changed, 105 insertions(+), 25 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a69c6f1bd0..5680bfd1e8 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 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 --> + Calculate route between points Registering device... OSMo connection problem : Stop OSMo diff --git a/OsmAnd/src/net/osmand/plus/GPXUtilities.java b/OsmAnd/src/net/osmand/plus/GPXUtilities.java index 03eb594513..81bbc3822a 100644 --- a/OsmAnd/src/net/osmand/plus/GPXUtilities.java +++ b/OsmAnd/src/net/osmand/plus/GPXUtilities.java @@ -123,6 +123,26 @@ public class GPXUtilities { public boolean isCloudmadeRouteFile() { return "cloudmade".equalsIgnoreCase(author); } + + public boolean hasRtePt() { + for(Route r : routes) { + if(r.points.size() > 0) { + return true; + } + } + return false; + } + + public boolean hasTrkpt() { + for(Track t : tracks) { + for (TrkSegment ts : t.segments) { + if (ts.points.size() > 0) { + return true; + } + } + } + return false; + } public void proccessPoints() { List> tpoints = new ArrayList>(); diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index b5b5042193..ba3c933c43 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -786,9 +786,10 @@ public class OsmandSettings { public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", true).makeProfile().cache(); public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", true).makeProfile().cache(); - public final OsmandPreference ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); - public final OsmandPreference SPEAK_GPX_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache(); - public final OsmandPreference CALC_GPX_ROUTE = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache(); + public final OsmandPreference GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache(); + public final OsmandPreference GPX_SPEAK_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache(); + public final OsmandPreference GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache(); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 029449caea..18a36c7402 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -473,9 +473,15 @@ public class MapActivityActions implements DialogProvider { } else { GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, mapActivity.getMyApplication() .getSettings()); - params.setCalculateOsmAndRouteParts(settings.ROUTE_CALC_OSMAND_PARTS.get()); - params.setAnnounceWaypoints(settings.SPEAK_GPX_WPT.get()); - params.setCalculateOsmAndRoute(settings.CALC_GPX_ROUTE.get()); + if (result.hasRtePt() && !result.hasTrkpt()) { + settings.GPX_CALCULATE_RTEPT.set(true); + } else { + settings.GPX_CALCULATE_RTEPT.set(false); + } + params.setCalculateOsmAndRouteParts(settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()); + params.setAnnounceWaypoints(settings.GPX_SPEAK_WPT.get()); + params.setUseIntermediatePointsRTE(settings.GPX_CALCULATE_RTEPT.get()); + params.setCalculateOsmAndRoute(settings.GPX_ROUTE_CALC.get()); List ps = params.getPoints(); mapActivity.getRoutingHelper().setGpxParams(params); settings.FOLLOW_THE_GPX_ROUTE.set(result.path); diff --git a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java index 9411e42af0..09b0796b43 100644 --- a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java +++ b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java @@ -128,13 +128,16 @@ public class FailSafeFuntions { final GPXRouteParamsBuilder gpxRoute; if (result != null) { gpxRoute = new GPXRouteParamsBuilder(result, settings); - if (settings.SPEAK_GPX_WPT.get()) { + if (settings.GPX_SPEAK_WPT.get()) { gpxRoute.setAnnounceWaypoints(true); } - if (settings.ROUTE_CALC_OSMAND_PARTS.get()) { + if (settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()) { gpxRoute.setCalculateOsmAndRouteParts(true); } - if(settings.CALC_GPX_ROUTE.get()) { + if (settings.GPX_CALCULATE_RTEPT.get()) { + gpxRoute.setUseIntermediatePointsRTE(true); + } + if(settings.GPX_ROUTE_CALC.get()) { gpxRoute.setCalculateOsmAndRoute(true); } } else { diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java index d9d7b92828..20899dfc47 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteProvider.java @@ -119,7 +119,8 @@ public class RouteProvider { private boolean reverse; private boolean leftSide; private boolean passWholeRoute; - public boolean calculateOsmAndRouteParts; + private boolean calculateOsmAndRouteParts; + private boolean useIntermediatePointsRTE; public GPXRouteParamsBuilder(GPXFile file, OsmandSettings settings){ leftSide = settings.DRIVING_REGION.get().leftHandDriving; @@ -142,6 +143,14 @@ public class RouteProvider { this.calculateOsmAndRouteParts = calculateOsmAndRouteParts; } + public void setUseIntermediatePointsRTE(boolean useIntermediatePointsRTE) { + this.useIntermediatePointsRTE = useIntermediatePointsRTE; + } + + public boolean isUseIntermediatePointsRTE() { + return useIntermediatePointsRTE; + } + public boolean isCalculateOsmAndRoute() { return calculateOsmAndRoute; } @@ -196,6 +205,7 @@ public class RouteProvider { boolean calculateOsmAndRoute; boolean passWholeRoute; boolean calculateOsmAndRouteParts; + boolean useIntermediatePointsRTE; public List getPoints() { return points; @@ -229,8 +239,9 @@ public class RouteProvider { boolean reverse = builder.reverse; passWholeRoute = builder.passWholeRoute; calculateOsmAndRouteParts = builder.calculateOsmAndRouteParts; + useIntermediatePointsRTE = builder.useIntermediatePointsRTE; boolean announceWaypoints = builder.announceWaypoints; - calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute; + builder.calculateOsmAndRoute = false; // Disabled temporary builder.calculateOsmAndRoute; if(file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)){ directions = parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10); if(reverse){ @@ -240,10 +251,12 @@ public class RouteProvider { } } else { // first of all check tracks - for (Track tr : file.tracks) { - for (TrkSegment tkSeg : tr.segments) { - for (WptPt pt : tkSeg.points) { - points.add(createLocation(pt)); + if (!useIntermediatePointsRTE) { + for (Track tr : file.tracks) { + for (TrkSegment tkSeg : tr.segments) { + for (WptPt pt : tkSeg.points) { + points.add(createLocation(pt)); + } } } } @@ -348,9 +361,13 @@ public class RouteProvider { return res; } - private RouteCalculationResult calculateGpxRoute(RouteCalculationParams routeParams) { + private RouteCalculationResult calculateGpxRoute(RouteCalculationParams routeParams) throws IOException { // get the closest point to start and to end GPXRouteParams gpxParams = routeParams.gpxRoute; + if(routeParams.gpxRoute.useIntermediatePointsRTE){ + final List intermediates = gpxParams.points; + return calculateOsmAndRouteWithIntermediatePoints(routeParams, intermediates); + } List gpxRoute ; int[] startI = new int[]{0}; int[] endI = new int[]{gpxParams.points.size()}; @@ -378,6 +395,28 @@ public class RouteProvider { + private RouteCalculationResult calculateOsmAndRouteWithIntermediatePoints(RouteCalculationParams routeParams, + final List intermediates) throws IOException { + RouteCalculationParams rp = new RouteCalculationParams(); + rp.calculationProgress = routeParams.calculationProgress; + rp.ctx = routeParams.ctx; + rp.mode = routeParams.mode; + rp.start = routeParams.start; + rp.end = routeParams.end; + rp.leftSide = routeParams.leftSide; + rp.type = routeParams.type; + rp.fast = routeParams.fast; + rp.previousToRecalculate = routeParams.previousToRecalculate; + rp.intermediates = new ArrayList(); + for(Location w : intermediates) { + rp.intermediates.add(new LatLon(w.getLatitude(), w.getLongitude())); + } + return findVectorMapsRoute(rp, false); + } + + + + private List calcDirections(int[] startI, int[] endI, final List inputDirections) { List directions = new ArrayList(); diff --git a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java index 2dadb2178a..45b4d2674e 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java +++ b/OsmAnd/src/net/osmand/plus/routing/RoutingHelper.java @@ -757,7 +757,7 @@ public class RoutingHelper { return; } final boolean onlineSourceWithoutInternet = !res.isCalculated() && params.type.isOnline() && !settings.isInternetConnectionAvailable(); - if (onlineSourceWithoutInternet && settings.ROUTE_CALC_OSMAND_PARTS.get()) { + if (onlineSourceWithoutInternet && settings.GPX_ROUTE_CALC_OSMAND_PARTS.get()) { if (params.previousToRecalculate != null && params.previousToRecalculate.isCalculated()) { res = provider.recalculatePartOfflineRoute(res, params); } diff --git a/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java b/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java index b462050ddc..8e11c831a2 100644 --- a/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java +++ b/OsmAnd/src/net/osmand/plus/views/controls/MapRoutePreferencesControl.java @@ -188,20 +188,23 @@ public class MapRoutePreferencesControl extends MapControls { } } else if (gpxParam.id == R.string.gpx_option_calculate_first_last_segment) { rp.setCalculateOsmAndRouteParts(selected); - settings.ROUTE_CALC_OSMAND_PARTS.set(selected); + settings.GPX_ROUTE_CALC_OSMAND_PARTS.set(selected); } else if (gpxParam.id == R.string.gpx_option_from_start_point) { rp.setPassWholeRoute(selected); } else if (gpxParam.id == R.string.announce_gpx_waypoints) { - settings.SPEAK_GPX_WPT.set(selected); + settings.GPX_SPEAK_WPT.set(selected); rp.setAnnounceWaypoints(selected); + } else if (gpxParam.id == R.string.use_points_as_intermediates) { + settings.GPX_CALCULATE_RTEPT.set(selected); + rp.setUseIntermediatePointsRTE(selected); } else if (gpxParam.id == R.string.calculate_osmand_route_gpx) { - settings.CALC_GPX_ROUTE.set(selected); + settings.GPX_ROUTE_CALC.set(selected); rp.setCalculateOsmAndRoute(selected); updateParameters(); } } if (gpxParam.id == R.string.calculate_osmand_route_without_internet) { - settings.ROUTE_CALC_OSMAND_PARTS.set(selected); + settings.GPX_ROUTE_CALC_OSMAND_PARTS.set(selected); } if (gpxParam.id == R.string.fast_route_mode) { settings.FAST_ROUTE_MODE.set(selected); @@ -215,18 +218,25 @@ public class MapRoutePreferencesControl extends MapControls { boolean osmandRouter = settings.ROUTER_SERVICE.get() == RouteService.OSMAND ; if(!osmandRouter) { list.add(new OtherLocalRoutingParameter(R.string.calculate_osmand_route_without_internet, - getString(R.string.calculate_osmand_route_without_internet), settings.ROUTE_CALC_OSMAND_PARTS.get())); + getString(R.string.calculate_osmand_route_without_internet), settings.GPX_ROUTE_CALC_OSMAND_PARTS.get())); list.add(new OtherLocalRoutingParameter(R.string.fast_route_mode, getString(R.string.fast_route_mode), settings.FAST_ROUTE_MODE.get())); return list; } if(rparams != null) { + GPXFile fl = rparams.getFile(); + if (fl.hasRtePt()) { + list.add(new OtherLocalRoutingParameter(R.string.use_points_as_intermediates, + getString(R.string.use_points_as_intermediates), rparams.isUseIntermediatePointsRTE())); + } list.add(new OtherLocalRoutingParameter(R.string.gpx_option_reverse_route, getString(R.string.gpx_option_reverse_route), rparams.isReverse())); - list.add(new OtherLocalRoutingParameter(R.string.gpx_option_from_start_point, + if (!rparams.isUseIntermediatePointsRTE()) { + list.add(new OtherLocalRoutingParameter(R.string.gpx_option_from_start_point, getString(R.string.gpx_option_from_start_point), rparams.isPassWholeRoute())); - list.add(new OtherLocalRoutingParameter(R.string.gpx_option_calculate_first_last_segment, - getString(R.string.gpx_option_calculate_first_last_segment), rparams.isCalculateOsmAndRouteParts())); + list.add(new OtherLocalRoutingParameter(R.string.gpx_option_calculate_first_last_segment, + getString(R.string.gpx_option_calculate_first_last_segment), rparams.isCalculateOsmAndRouteParts())); + } list.add(new OtherLocalRoutingParameter(R.string.announce_gpx_waypoints, getString(R.string.announce_gpx_waypoints), rparams.isAnnounceWaypoints())); // Temporary disabled From 8991595423a334b6d01ea1a7e310ae90dfdecb3c Mon Sep 17 00:00:00 2001 From: vshcherb Date: Wed, 21 May 2014 11:24:46 +0200 Subject: [PATCH 15/17] fix crash --- OsmAnd/res/values/strings.xml | 4 ++++ OsmAnd/src/net/osmand/plus/OsmandSettings.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5680bfd1e8..f68ccd0c38 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 --> + Changes in 1.8: + * Calculate route between route points of GPX track + * Changed layout of countries for downloads (support local names search) + Calculate route between points Registering device... OSMo connection problem : diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index ba3c933c43..6f88065da9 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -632,7 +632,8 @@ public class OsmandSettings { public final OsmandPreference DRIVING_REGION = new EnumIntPreference( "default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) { protected boolean setValue(Object prefs, DrivingRegion val) { - ((CommonPreference)METRIC_SYSTEM).cachedValue = null; + //((CommonPreference)METRIC_SYSTEM).cachedValue = null; + ((CommonPreference)METRIC_SYSTEM).set(DRIVING_REGION.get().defMetrics); return super.setValue(prefs, val); }; }.makeGlobal().cache(); @@ -640,7 +641,7 @@ public class OsmandSettings { // this value string is synchronized with settings_pref.xml preference name // cache of metrics constants as they are used very often public final OsmandPreference METRIC_SYSTEM = new EnumIntPreference( - "default_metric_system_2", MetricsConstants.KILOMETERS_AND_METERS, MetricsConstants.values()){ + "default_metric_system", MetricsConstants.KILOMETERS_AND_METERS, MetricsConstants.values()){ protected MetricsConstants getDefaultValue() { return DRIVING_REGION.get().defMetrics; }; From 8d3319daa517d31a431f1c29e2e519c57986d898 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Wed, 21 May 2014 19:19:30 +0200 Subject: [PATCH 16/17] Change osmo settings --- OsmAnd/res/values/strings.xml | 25 ++++--- .../activities/ShowRouteInfoActivity.java | 13 +--- .../src/net/osmand/plus/osmo/OsMoGroups.java | 6 ++ .../src/net/osmand/plus/osmo/OsMoPlugin.java | 63 ++++------------ .../src/net/osmand/plus/osmo/OsMoService.java | 49 ++++++++++--- .../src/net/osmand/plus/osmo/OsMoThread.java | 61 +++++++++++----- .../src/net/osmand/plus/osmo/OsMoTracker.java | 10 +++ .../plus/osmo/SettingsOsMoActivity.java | 71 +++++++++++++++---- 8 files changed, 187 insertions(+), 111 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index f68ccd0c38..be68b808cc 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,21 +9,28 @@ 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 --> + Personal tracker id + Click to view or share tracker id. + Using tracker id connected devices will be able to monitor all movements of this device! To disconnect select Regenerate option. + Session token %1$s + Waiting for authorization... + Locations sent %1$d (in buffer %2$d) + Connection established : %1$s + OsMo connection problem : + Unique device id Changes in 1.8: * Calculate route between route points of GPX track * Changed layout of countries for downloads (support local names search) Calculate route between points - Registering device... - OSMo connection problem : - Stop OSMo - Start OSMo - Unique device id - View unique device registration key and other monitoring specific settings - OSMo (OpenStreetMap-Monitoring) + Stop OsMo session + Start OsMo session + Debug information + + OsMo (OpenStreetMap-Monitoring) OpenStreetMap-Monitoring - Advanced Live Monitoring with lots of features for remote control http://osmo.mobi - OSMo (Advanced Live Monitoring) - OSMo + OsMo (Advanced Live Monitoring) + OsMo Display position always in center Voice Miscallenious diff --git a/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java b/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java index 023bbbb52a..ba780261b1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java @@ -20,6 +20,7 @@ import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.views.TurnPathHelper; import net.osmand.plus.views.controls.MapRouteInfoControl; +import net.osmand.util.Algorithms; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.LayoutInflater; @@ -156,16 +157,8 @@ public class ShowRouteInfoActivity extends OsmandListActivity { } private String getTimeDescription(RouteDirectionInfo model) { - int seconds = model.getExpectedTime() % 60; - int min = (model.getExpectedTime() / 60) % 60; - int hours = (model.getExpectedTime() / 3600); - String timeText; - if (hours == 0) { - timeText = String.format("%02d:%02d", min, seconds); //$NON-NLS-1$ - } else { - timeText = String.format("%d:%02d:%02d", hours, min, seconds); //$NON-NLS-1$ - } - return timeText; + final int timeInSeconds = model.getExpectedTime(); + return Algorithms.formatDuration(timeInSeconds); } } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java index 956f6f2682..34737c7709 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java @@ -87,6 +87,9 @@ public class OsMoGroups implements OsMoReactor { try { JSONObject obj = new JSONObject(grp); parseGroupUsers(mainGroup, obj); + if(!obj.has("groups")) { + return; + } JSONArray groups = obj.getJSONArray("groups"); for (int i = 0; i < groups.length(); i++) { JSONObject o = (JSONObject) groups.get(i); @@ -154,6 +157,9 @@ public class OsMoGroups implements OsMoReactor { } private void parseGroupUsers(OsMoGroup gr, JSONObject obj) throws JSONException { + if(!obj.has("users")) { + return; + } JSONArray users = obj.getJSONArray("users"); for (int i = 0; i < users.length(); i++) { JSONObject o = (JSONObject) users.get(i); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index 13f5e213b4..afd11d1d2a 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -11,11 +11,8 @@ import net.osmand.plus.activities.SettingsActivity; import net.osmand.plus.views.MonitoringInfoControl; import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices; import net.osmand.plus.views.OsmandMapTileView; -import android.app.ProgressDialog; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.os.AsyncTask; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; @@ -38,9 +35,16 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer @Override public boolean init(final OsmandApplication app) { + service.connect(true); return true; } + @Override + public void disable(OsmandApplication app) { + super.disable(app); + service.disconnect(); + } + @Override public void updateLocation(Location location) { if (service.isConnected()) { @@ -67,63 +71,22 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer lock.addMonitorActions(this); } } - - public AsyncTask - getRegisterDeviceTask(final Context uiContext, final Runnable postAction) { - return new AsyncTask() { - private ProgressDialog dlg; - protected void onPreExecute() { - dlg = ProgressDialog.show(uiContext, "", app.getString(R.string.osmo_register_device)); - }; - @Override - protected void onPostExecute(Exception result) { - if(dlg.isShowing()) { - dlg.dismiss(); - } - if (result != null) { - result.printStackTrace(); - app.showToastMessage(app.getString(R.string.osmo_io_error) + result.getMessage()); - } else if(postAction != null) { - postAction.run(); - } - } - - @Override - protected Exception doInBackground(Void... params) { - return service.registerOsmoDeviceKey(); - } - }; - } - - @Override public void addMonitorActions(ContextMenuAdapter qa, MonitoringInfoControl li, final OsmandMapTileView view) { final boolean off = !service.isConnected(); - qa.item(off ? R.string.osmo_mode_off : R.string.osmo_mode_on) .icon(off ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) .listen(new OnContextMenuClick() { @Override public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) { - if(app.getSettings().OSMO_DEVICE_KEY.get().length() == 0) { - getRegisterDeviceTask(view.getContext(), new Runnable() { - public void run() { - service.connect(true); - } - }); - return; - } - if(off) { + if (off) { service.connect(true); } else { service.disconnect(); } } - - - }).reg(); qa.item("Test (send)").icons(R.drawable.ic_action_grefresh_dark, R.drawable.ic_action_grefresh_light) .listen(new OnContextMenuClick() { @@ -158,14 +121,16 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public String getId() { return ID; } - + public OsMoGroups getGroups() { return groups; } - - + public OsMoTracker getTracker() { return tracker; } - + + public OsMoService getService() { + return service; + } } diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java index 7476f67727..68bf90b1c4 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java @@ -35,6 +35,7 @@ public class OsMoService implements OsMoSender { private ConcurrentLinkedQueue commands = new ConcurrentLinkedQueue(); private OsmandApplication app; private static final Log log = PlatformUtil.getLog(OsMoService.class); + private String lastRegistrationError = null; @@ -47,6 +48,15 @@ public class OsMoService implements OsMoSender { return thread != null && thread.isConnected(); } + public long getConnectionTime() { + return thread == null || !thread.isConnected() ? System.currentTimeMillis() : thread.getConnectionTime(); + } + + + public String getLastRegistrationError() { + return lastRegistrationError; + } + public boolean connect(boolean forceReconnect) { if(thread != null) { if(!forceReconnect ) { @@ -85,7 +95,7 @@ public class OsMoService implements OsMoSender { } - public Exception registerOsmoDeviceKey() { + public String registerOsmoDeviceKey() throws IOException { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth"); try { @@ -107,16 +117,13 @@ public class OsMoService implements OsMoSender { log.info("Authorization key : " + r); final JSONObject obj = new JSONObject(r); if(obj.has("error")) { - return new RuntimeException(obj.getString("error")); + lastRegistrationError = obj.getString("error"); + throw new RuntimeException(obj.getString("error")); } app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key")); - return null; - } catch (ClientProtocolException e) { - return e; - } catch (IOException e) { - return e; + return obj.getString("key"); } catch (JSONException e) { - return e; + throw new IOException(e); } } @@ -124,12 +131,28 @@ public class OsMoService implements OsMoSender { public String hostName; public String port; public String token; - + // after auth + public String protocol = ""; + public String groupTrackerId; + public String trackerId; + public String username; + public long serverTimeDelta; + public long motdTimestamp; + } + + public SessionInfo getCurrentSessionInfo() { + if(thread == null) { + return null; + } + return thread.getSessionInfo(); } - public SessionInfo getSessionToken() throws IOException { + public SessionInfo prepareSessionToken() throws IOException { String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get(); + if(deviceKey.length() == 0) { + deviceKey = registerOsmoDeviceKey(); + } HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare"); try { @@ -148,14 +171,18 @@ public class OsMoService implements OsMoSender { log.info("Authorization key : " + r); final JSONObject obj = new JSONObject(r); if(obj.has("error")) { + lastRegistrationError = obj.getString("error"); throw new RuntimeException(obj.getString("error")); } if(!obj.has("address")) { + lastRegistrationError = "Host name not specified"; throw new RuntimeException("Host name not specified"); } if(!obj.has("token")) { - throw new RuntimeException("Token not specified"); + lastRegistrationError = "Token not specified by server"; + throw new RuntimeException("Token not specified by server"); } + SessionInfo si = new SessionInfo(); String a = obj.getString("address"); int i = a.indexOf(':'); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index fc24a6be72..8f30319853 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -48,8 +48,9 @@ public class OsMoThread { private int authorized = 0; // 1 - send, 2 - authorized private OsMoService service; - private SessionInfo token = null; + private SessionInfo sessionInfo = null; private SocketChannel activeChannel; + private long connectionTime; private ByteBuffer pendingSendCommand; private String readCommand = ""; private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048); @@ -66,17 +67,6 @@ public class OsMoThread { HandlerThread h = new HandlerThread("OSMo Service"); h.start(); serviceThread = new Handler(h.getLooper()); - serviceThread.post(new Runnable() { - - @Override - public void run() { - try { - initConnection(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); scheduleHeartbeat(HEARTBEAT_DELAY); } @@ -85,17 +75,18 @@ public class OsMoThread { } protected void initConnection() throws IOException { - if (token == null) { - token = service.getSessionToken(); + if (sessionInfo == null) { + sessionInfo = service.prepareSessionToken(); } authorized = 0; reconnect = false; selector = Selector.open(); SocketChannel activeChannel = SocketChannel.open(); activeChannel.configureBlocking(true); - activeChannel.connect(new InetSocketAddress(token.hostName, Integer.parseInt(token.port))); + activeChannel.connect(new InetSocketAddress(sessionInfo.hostName, Integer.parseInt(sessionInfo.port))); activeChannel.configureBlocking(false); SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); + connectionTime = System.currentTimeMillis(); if (this.activeChannel != null) { stopChannel(); } @@ -267,8 +258,11 @@ public class OsMoThread { if(header.equalsIgnoreCase("TOKEN")) { if(!error){ authorized = 2; - // TODO delete - service.showErrorMessage("OSMo authorization successfull"); + try { + parseAuthCommand(data, obj); + } catch (JSONException e) { + service.showErrorMessage(e.getMessage()); + } } continue; } @@ -285,6 +279,33 @@ public class OsMoThread { } } + private void parseAuthCommand(String data, JSONObject obj) throws JSONException { + if(sessionInfo != null) { + if(obj.has("protocol")) { + sessionInfo.protocol = obj.getString("protocol"); + } + if(obj.has("now")) { + sessionInfo.serverTimeDelta = obj.getLong("now") - System.currentTimeMillis(); + } + if(obj.has("name")) { + sessionInfo.username = obj.getString("name"); + } + if (obj.has("motd")) { + sessionInfo.motdTimestamp = obj.getLong("motd"); + } + if(obj.has("tracker_id")) { + sessionInfo.trackerId= obj.getString("tracker_id"); + } + if(obj.has("group_tracker_id")) { + sessionInfo.groupTrackerId= obj.getString("group_tracker_id"); + } + } + } + + public long getConnectionTime() { + return connectionTime; + } + private void writeCommands() throws UnsupportedEncodingException, IOException { if (pendingSendCommand == null) { pendingSendCommand = getNewPendingSendCommand(); @@ -303,7 +324,7 @@ public class OsMoThread { private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException { if(authorized == 0) { - String auth = "TOKEN|"+ token.token; + String auth = "TOKEN|"+ sessionInfo.token; log.info("OSMO send:" + auth); authorized = 1; return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8")); @@ -321,6 +342,10 @@ public class OsMoThread { } return null; } + + public SessionInfo getSessionInfo() { + return sessionInfo; + } private StringBuilder prepareCommand(String l) { boolean addNL = true; diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index 1a160367d3..f2204791d3 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -16,6 +16,7 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { private boolean startSendingLocations; private OsmandMapTileView view; private OsMoService service; + private int locationsSent = 0; public OsMoTracker(OsMoService service) { this.service = service; @@ -71,6 +72,7 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { if((System.currentTimeMillis() - loc.getTime()) > 30000 && loc.getTime() != 0) { cmd.append("T").append(loc.getTime()); } + locationsSent ++; return cmd.toString(); } return null; @@ -81,6 +83,14 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { bufferOfLocations.add(location); } } + + public int getLocationsSent() { + return locationsSent; + } + + public int getBufferLocationsSize() { + return bufferOfLocations.size(); + } public void sendCoordinate(double lat, double lon) { Location l = new Location("test"); diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java index df82665b69..31b0d75254 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java @@ -1,21 +1,30 @@ package net.osmand.plus.osmo; +import net.osmand.access.AccessibleToast; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.R; import net.osmand.plus.activities.SettingsBaseActivity; +import net.osmand.plus.osmo.OsMoService.SessionInfo; +import net.osmand.util.Algorithms; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceScreen; +import android.text.format.DateFormat; +import android.util.TimeUtils; import android.widget.ProgressBar; +import android.widget.Toast; public class SettingsOsMoActivity extends SettingsBaseActivity { public static final String MORE_VALUE = "MORE_VALUE"; public static final String DEFINE_EDIT = "DEFINE_EDIT"; - private Preference uuid; + private Preference debugPref; + private Preference trackerId; @Override @@ -24,27 +33,61 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { getSupportActionBar().setTitle(R.string.osmo_settings); PreferenceScreen grp = getPreferenceScreen(); - uuid = new Preference(this); - uuid.setTitle(R.string.osmo_settings_uuid); - uuid.setSummary(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()); - uuid.setOnPreferenceClickListener(this); - grp.addPreference(uuid); + trackerId = new Preference(this); + trackerId.setTitle(R.string.osmo_tracker_id); + trackerId.setSummary(R.string.osmo_tracker_id_descr); + debugPref = new Preference(this); + debugPref.setTitle(R.string.osmo_settings_debug); + updateDebugPref(); + grp.addPreference(debugPref); } + + private void updateDebugPref() { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + OsMoService service = plugin.getService(); + OsMoTracker tracker = plugin.getTracker(); + StringBuilder s = new StringBuilder(); + s.append(getString(R.string.osmo_settings_uuid)).append(" : ") + .append(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()).append("\n"); + if(service.isConnected()) { + int seconds = (int) ((System.currentTimeMillis() - service.getConnectionTime()) / 1000); + s.append(getString(R.string.osmo_conn_successfull, Algorithms.formatDuration(seconds))).append("\n"); + SessionInfo si = service.getCurrentSessionInfo(); + if(si == null) { + s.append(getString(R.string.osmo_auth_pending)).append("\n"); + } else { + s.append(getString(R.string.osmo_session_token, si.token)).append("\n"); + } + } else { + s.append(getString(R.string.osmo_io_error) + service.getLastRegistrationError()).append("\n"); + } + s.append(getString(R.string.osmo_locations_sent, + tracker.getLocationsSent(), + tracker.getBufferLocationsSize())); + debugPref.setSummary(s.toString().trim()); + debugPref.setOnPreferenceClickListener(this); + } @Override public boolean onPreferenceClick(Preference preference) { - if (preference == uuid) { - OsMoPlugin.getEnabledPlugin(OsMoPlugin.class).getRegisterDeviceTask(this, new Runnable() { - @Override - public void run() { - updateAllSettings(); - uuid.setSummary(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()); - } - }).execute(); + if (preference == debugPref) { + updateDebugPref(); return true; + } else if(preference == trackerId) { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + OsMoService service = plugin.getService(); + SessionInfo ci = service.getCurrentSessionInfo(); + if(ci == null || ci.trackerId == null) { + AccessibleToast.makeText(this, R.string.osmo_auth_pending, Toast.LENGTH_SHORT).show(); + } else { + Builder bld = new AlertDialog.Builder(this); + bld.setTitle(R.string.osmo_tracker_id); + bld.setMessage(ci.trackerId); + bld.show(); + } } return super.onPreferenceClick(preference); } From 882c45bdd63c1965a7b3b3e5c37efbe6b73ef363 Mon Sep 17 00:00:00 2001 From: vshcherb Date: Wed, 21 May 2014 20:37:10 +0200 Subject: [PATCH 17/17] Fix osmo settings --- OsmAnd/res/values/strings.xml | 7 +++- .../src/net/osmand/plus/OsmandSettings.java | 2 + .../src/net/osmand/plus/osmo/OsMoPlugin.java | 22 +++++++---- .../src/net/osmand/plus/osmo/OsMoThread.java | 12 +++--- .../src/net/osmand/plus/osmo/OsMoTracker.java | 24 ++++++------ .../plus/osmo/SettingsOsMoActivity.java | 38 ++++++++++++++++--- 6 files changed, 71 insertions(+), 34 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index be68b808cc..e2753608c9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,10 +9,12 @@ 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 --> + Automatically start tracker session and send locations after application startup + Automatically start tracker session Personal tracker id Click to view or share tracker id. Using tracker id connected devices will be able to monitor all movements of this device! To disconnect select Regenerate option. - Session token %1$s + Session token : %1$s Waiting for authorization... Locations sent %1$d (in buffer %2$d) Connection established : %1$s @@ -23,10 +25,11 @@ * Changed layout of countries for downloads (support local names search) Calculate route between points + Restart OsMo session Stop OsMo session Start OsMo session Debug information - + Configure monitoring settings and setup personal monitoring channel OsMo (OpenStreetMap-Monitoring) OpenStreetMap-Monitoring - Advanced Live Monitoring with lots of features for remote control http://osmo.mobi OsMo (Advanced Live Monitoring) diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 6f88065da9..0ee65645d4 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -828,6 +828,8 @@ public class OsmandSettings { public final OsmandPreference OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal(); + public final OsmandPreference OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal(); + public final OsmandPreference OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal(); // this value string is synchronized with settings_pref.xml preference name diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java index afd11d1d2a..8e31f2eb5e 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java @@ -28,7 +28,9 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer public OsMoPlugin(final OsmandApplication app) { service = new OsMoService(app); tracker = new OsMoTracker(service); - tracker.enableTracker(); + if(app.getSettings().OSMO_AUTO_SEND_LOCATIONS.get()) { + tracker.enableTracker(); + } groups = new OsMoGroups(service, tracker, app.getSettings()); this.app = app; } @@ -74,17 +76,23 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer @Override public void addMonitorActions(ContextMenuAdapter qa, MonitoringInfoControl li, final OsmandMapTileView view) { - final boolean off = !service.isConnected(); - qa.item(off ? R.string.osmo_mode_off : R.string.osmo_mode_on) - .icon(off ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) + //final boolean off = !service.isConnected(); + final boolean autosend = app.getSettings().OSMO_AUTO_SEND_LOCATIONS.get(); + final boolean offTracker = tracker.isEnabledTracker(); + qa.item(autosend ? R.string.osmo_mode_restart : + ( offTracker ? R.string.osmo_mode_off : R.string.osmo_mode_on)) + .icon(offTracker ? R.drawable.monitoring_rec_inactive : R.drawable.monitoring_rec_big) .listen(new OnContextMenuClick() { @Override public void onContextMenuClick(int itemId, int pos, boolean isChecked, DialogInterface dialog) { - if (off) { - service.connect(true); + if(autosend) { + tracker.disableTracker(); + tracker.enableTracker(); + } else if (offTracker) { + tracker.enableTracker(); } else { - service.disconnect(); + tracker.disableTracker(); } } }).reg(); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java index 8f30319853..cb79345c64 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java @@ -128,14 +128,12 @@ public class OsMoThread { protected void checkAsyncSocket() { long delay = HEARTBEAT_DELAY; try { - if (selector == null) { - stopThread = true; +// if (selector == null) { +// stopThread = true; + if(activeChannel == null || reconnect) { + initConnection(); } else { - if(activeChannel == null || reconnect) { - initConnection(); - } else { - checkSelectedKeys(); - } + checkSelectedKeys(); } } catch (Exception e) { log.info("Exception selecting socket", e); diff --git a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java index f2204791d3..4d7005d299 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java +++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java @@ -12,7 +12,6 @@ import org.json.JSONObject; public class OsMoTracker implements OsMoSender, OsMoReactor { private ConcurrentLinkedQueue bufferOfLocations = new ConcurrentLinkedQueue(); private Map otherLocations = new ConcurrentHashMap(); - private boolean trackerStarted; private boolean startSendingLocations; private OsmandMapTileView view; private OsMoService service; @@ -24,12 +23,22 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { service.registerReactor(this); } + public boolean isEnabledTracker() { + return startSendingLocations; + } + public void enableTracker() { - startSendingLocations = true; + if(!startSendingLocations) { + startSendingLocations = true; + service.pushCommand("TRACKER_SESSION_OPEN"); + } } public void disableTracker() { - startSendingLocations = false; + if(startSendingLocations) { + startSendingLocations = false; + service.pushCommand("TRACKER_SESSION_CLOSE"); + } } public void startTrackingId(String id) { @@ -44,15 +53,6 @@ public class OsMoTracker implements OsMoSender, OsMoReactor { @Override public String nextSendCommand(OsMoThread thread) { - if (trackerStarted != startSendingLocations) { - if (!trackerStarted) { - trackerStarted = true; - return "TRACKER_SESSION_OPEN"; - } else { - trackerStarted = false; - return "TRACKER_SESSION_CLOSE"; - } - } if(!bufferOfLocations.isEmpty()){ Location loc = bufferOfLocations.poll(); StringBuilder cmd = new StringBuilder("T|"); diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java index 31b0d75254..718eb7dc4f 100644 --- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java +++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java @@ -12,6 +12,7 @@ import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; +import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceScreen; import android.text.format.DateFormat; @@ -25,6 +26,7 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { public static final String DEFINE_EDIT = "DEFINE_EDIT"; private Preference debugPref; private Preference trackerId; + private CheckBoxPreference sendLocationsref; @Override @@ -34,13 +36,21 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { PreferenceScreen grp = getPreferenceScreen(); + trackerId = new Preference(this); trackerId.setTitle(R.string.osmo_tracker_id); trackerId.setSummary(R.string.osmo_tracker_id_descr); + trackerId.setOnPreferenceClickListener(this); + grp.addPreference(trackerId); + + 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); debugPref = new Preference(this); debugPref.setTitle(R.string.osmo_settings_debug); - + debugPref.setOnPreferenceClickListener(this); updateDebugPref(); grp.addPreference(debugPref); } @@ -50,8 +60,6 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { OsMoService service = plugin.getService(); OsMoTracker tracker = plugin.getTracker(); StringBuilder s = new StringBuilder(); - s.append(getString(R.string.osmo_settings_uuid)).append(" : ") - .append(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()).append("\n"); if(service.isConnected()) { int seconds = (int) ((System.currentTimeMillis() - service.getConnectionTime()) / 1000); s.append(getString(R.string.osmo_conn_successfull, Algorithms.formatDuration(seconds))).append("\n"); @@ -62,13 +70,18 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { s.append(getString(R.string.osmo_session_token, si.token)).append("\n"); } } else { - s.append(getString(R.string.osmo_io_error) + service.getLastRegistrationError()).append("\n"); + String err = service.getLastRegistrationError(); + if(err == null) { + err = "..."; + } + s.append(getString(R.string.osmo_io_error) + err).append("\n"); } s.append(getString(R.string.osmo_locations_sent, tracker.getLocationsSent(), - tracker.getBufferLocationsSize())); + tracker.getBufferLocationsSize())).append("\n"); + s.append(getString(R.string.osmo_settings_uuid)).append(" : ") + .append(getMyApplication().getSettings().OSMO_DEVICE_KEY.get().toUpperCase()).append("\n"); debugPref.setSummary(s.toString().trim()); - debugPref.setOnPreferenceClickListener(this); } @Override @@ -91,6 +104,19 @@ public class SettingsOsMoActivity extends SettingsBaseActivity { } return super.onPreferenceClick(preference); } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean p = super.onPreferenceChange(preference, newValue); + String id = preference.getKey(); + if (id.equals(settings.OSMO_AUTO_SEND_LOCATIONS.getId())) { + if ((Boolean) newValue) { + final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class); + plugin.getTracker().enableTracker(); + } + } + return p; + } public void updateAllSettings() {