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
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 347b324f54..e2753608c9 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -9,15 +9,31 @@
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
-->
- OSMo connection problem :
- Stop OSMo
- Start OSMo
+ 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
+ Waiting for authorization...
+ Locations sent %1$d (in buffer %2$d)
+ Connection established : %1$s
+ OsMo connection problem :
Unique device id
- View unique device registration key and other monitoring specific settings
- OSMo (OpenStreetMap-Monitoring)
+ 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
+ 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)
- OSMo
+ OsMo (Advanced Live Monitoring)
+ OsMo
Display position always in center
Voice
Miscallenious
@@ -1441,6 +1457,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/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/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/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 3766b5154a..84cc9deeca 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;
};
@@ -786,9 +787,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();
@@ -824,6 +826,12 @@ 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();
+
+ 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
public final OsmandPreference DEBUG_RENDERING_INFO = new BooleanPreference("debug_rendering", false).makeGlobal();
@@ -1659,6 +1667,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/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()){
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/activities/SettingsGeneralActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsGeneralActivity.java
index 6f518c4709..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;
@@ -138,16 +139,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 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);
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/osmo/OsMoGroups.java b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
new file mode 100644
index 0000000000..34737c7709
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
@@ -0,0 +1,283 @@
+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);
+ if(!obj.has("groups")) {
+ return;
+ }
+ 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 {
+ if(!obj.has("users")) {
+ return;
+ }
+ 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 1adf4cd150..8e31f2eb5e 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoPlugin.java
@@ -1,7 +1,6 @@
package net.osmand.plus.osmo;
import net.osmand.Location;
-import net.osmand.PlatformUtil;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
import net.osmand.plus.OsmandApplication;
@@ -12,36 +11,42 @@ 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 android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
-import android.provider.Settings;
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;
+ private OsMoGroups groups;
public OsMoPlugin(final OsmandApplication app) {
- service = new OsMoService();
+ service = new OsMoService(app);
tracker = new OsMoTracker(service);
+ if(app.getSettings().OSMO_AUTO_SEND_LOCATIONS.get()) {
+ tracker.enableTracker();
+ }
+ groups = new OsMoGroups(service, tracker, app.getSettings());
this.app = app;
}
@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()) {
@@ -49,10 +54,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);
@@ -72,27 +73,28 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
lock.addMonitorActions(this);
}
}
-
-
@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();
qa.item("Test (send)").icons(R.drawable.ic_action_grefresh_dark, R.drawable.ic_action_grefresh_light)
.listen(new OnContextMenuClick() {
@@ -127,4 +129,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/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 65a6fdbe13..68bf90b1c4 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoService.java
@@ -1,32 +1,62 @@
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 java.util.concurrent.ConcurrentLinkedQueue;
-public class OsMoService {
- //public static int NUMBER_OF_TRIES_TO_RECONNECT = 20;
-
+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;
+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;
+
+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);
+ private String lastRegistrationError = null;
- public interface OsMoSender {
-
- public String nextSendCommand();
- }
- public interface OsMoReactor {
-
- public boolean acceptCommand(String command);
-
- }
- public OsMoService() {
+ public OsMoService(OsmandApplication app) {
+ this.app = app;
+ listSenders.add(this);
}
public boolean isConnected() {
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 ) {
@@ -34,7 +64,7 @@ public class OsMoService {
}
thread.stopConnection();
}
- thread = new OsMoThread(listSenders, listReactors);
+ thread = new OsMoThread(this, listSenders, listReactors);
return true;
}
@@ -65,4 +95,124 @@ public class OsMoService {
}
+ public String registerOsmoDeviceKey() throws IOException {
+ 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")) {
+ lastRegistrationError = obj.getString("error");
+ throw new RuntimeException(obj.getString("error"));
+ }
+ app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key"));
+ return obj.getString("key");
+ } catch (JSONException e) {
+ throw new IOException(e);
+ }
+ }
+
+ public static class SessionInfo {
+ 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 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 {
+ // 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")) {
+ 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")) {
+ 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(':');
+ si.hostName = a.substring(0, i);
+ si.port = a.substring(i + 1);
+ 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);
+ }
+
+ 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 f4d36cefd1..cb79345c64 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoThread.java
@@ -10,65 +10,63 @@ 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 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;
+import org.json.JSONException;
+import org.json.JSONObject;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
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 boolean reconnect;
private Selector selector;
private List listSenders;
private List listReactors;
+ private int authorized = 0; // 1 - send, 2 - authorized
+ private OsMoService service;
+ private SessionInfo sessionInfo = null;
private SocketChannel activeChannel;
+ private long connectionTime;
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(OsMoService service, List listSenders, List listReactors) {
+ this.service = service;
this.listSenders = listSenders;
this.listReactors = listReactors;
// start thread to receive events from OSMO
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);
}
@@ -77,16 +75,38 @@ public class OsMoThread {
}
protected void initConnection() throws IOException {
+ if (sessionInfo == null) {
+ sessionInfo = service.prepareSessionToken();
+ }
+ authorized = 0;
+ reconnect = false;
+ selector = Selector.open();
+ SocketChannel activeChannel = SocketChannel.open();
+ activeChannel.configureBlocking(true);
+ 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();
+ }
+ this.activeChannel = activeChannel;
+ key.attach(new Integer(++activeConnectionId));
+
+ }
+
+ public String format(String cmd, Map params) {
+ JSONObject json;
try {
- 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;
+ 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);
}
}
@@ -102,25 +122,18 @@ public class OsMoThread {
}
public boolean isConnected() {
- return connectionStarted == -1;
+ return activeChannel != null;
}
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 && connectionStarted != -1 && !activeChannel.isConnectionPending()) {
- // connection ready
- connectionStarted = -1;
- }
- if ((connectionStarted != -1 && System.currentTimeMillis() - connectionStarted > CONNECTION_DELAY)
- || activeChannel == null) {
- initConnection();
- } else {
- checkSelectedKeys();
- }
+ checkSelectedKeys();
}
} catch (Exception e) {
log.info("Exception selecting socket", e);
@@ -130,7 +143,7 @@ public class OsMoThread {
activeChannel = null;
}
if (failures++ > LIMIT_OF_FAILURES_RECONNECT) {
- stopChannel();
+ reconnect = true;
}
}
if (stopThread) {
@@ -186,12 +199,14 @@ public class OsMoThread {
while (hasSomethingToRead) {
pendingReadCommand.clear();
int read = activeChannel.read(pendingReadCommand);
- if (pendingReadCommand.hasRemaining()) {
+ if (!pendingReadCommand.hasRemaining()) {
hasSomethingToRead = true;
} 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;
@@ -205,46 +220,130 @@ 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();
+ log.info("OSMO get:"+cmd);
+ 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();
+ }
+ }
+ boolean error = false;
+ if(obj != null && obj.has("error")) {
+ error = true;
+ try {
+ service.showErrorMessage(obj.getString("error"));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ if(header.equalsIgnoreCase("TOKEN")) {
+ if(!error){
+ authorized = 2;
+ try {
+ parseAuthCommand(data, obj);
+ } catch (JSONException e) {
+ service.showErrorMessage(e.getMessage());
+ }
+ }
+ 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 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) {
- getNewPendingSendCommand();
+ pendingSendCommand = getNewPendingSendCommand();
}
while (pendingSendCommand != null) {
activeChannel.write(pendingSendCommand);
if (!pendingSendCommand.hasRemaining()) {
- pendingSendCommand = null;
- getNewPendingSendCommand();
- }
- }
- }
-
- private void getNewPendingSendCommand() throws UnsupportedEncodingException {
- for (OsMoSender s : listSenders) {
- String l = s.nextSendCommand();
- if (l != null) {
- StringBuilder res = prepareCommand(l);
- pendingSendCommand = ByteBuffer.wrap(res.toString().getBytes("UTF-8"));
+ pendingSendCommand = getNewPendingSendCommand();
+ } else {
break;
}
}
}
+
+
+
+ private ByteBuffer getNewPendingSendCommand() throws UnsupportedEncodingException {
+ if(authorized == 0) {
+ String auth = "TOKEN|"+ sessionInfo.token;
+ log.info("OSMO send:" + auth);
+ authorized = 1;
+ return ByteBuffer.wrap(prepareCommand(auth).toString().getBytes("UTF-8"));
+ }
+ if(authorized == 1) {
+ return null;
+ }
+ for (OsMoSender s : listSenders) {
+ 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"));
+ }
+ }
+ return null;
+ }
+
+ public SessionInfo getSessionInfo() {
+ return sessionInfo;
+ }
private StringBuilder prepareCommand(String l) {
boolean addNL = true;
@@ -270,4 +369,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..4d7005d299 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/OsMoTracker.java
@@ -1,19 +1,58 @@
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.OsMoSender;
+import net.osmand.plus.views.OsmandMapTileView;
-public class OsMoTracker implements OsMoSender {
- private LinkedList bufferOfLocations = new LinkedList();
+import org.json.JSONObject;
+
+public class OsMoTracker implements OsMoSender, OsMoReactor {
+ private ConcurrentLinkedQueue bufferOfLocations = new ConcurrentLinkedQueue();
+ private Map otherLocations = new ConcurrentHashMap();
+ private boolean startSendingLocations;
+ private OsmandMapTileView view;
+ private OsMoService service;
+ private int locationsSent = 0;
public OsMoTracker(OsMoService service) {
+ this.service = service;
service.registerSender(this);
+ service.registerReactor(this);
+ }
+
+ public boolean isEnabledTracker() {
+ return startSendingLocations;
+ }
+
+ public void enableTracker() {
+ if(!startSendingLocations) {
+ startSendingLocations = true;
+ service.pushCommand("TRACKER_SESSION_OPEN");
+ }
+ }
+
+ public void disableTracker() {
+ if(startSendingLocations) {
+ startSendingLocations = false;
+ service.pushCommand("TRACKER_SESSION_CLOSE");
+ }
+ }
+
+ public void startTrackingId(String id) {
+ service.pushCommand("LISTEN|"+id);
+ otherLocations.put(id, null);
+ }
+
+ public void stopTrackingId(String id) {
+ service.pushCommand("UNLISTEN|"+id);
+ otherLocations.remove(id);
}
@Override
- public String nextSendCommand() {
+ public String nextSendCommand(OsMoThread thread) {
if(!bufferOfLocations.isEmpty()){
Location loc = bufferOfLocations.poll();
StringBuilder cmd = new StringBuilder("T|");
@@ -27,13 +66,30 @@ 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 && loc.getTime() != 0) {
+ cmd.append("T").append(loc.getTime());
+ }
+ locationsSent ++;
return cmd.toString();
}
return null;
}
public void sendCoordinate(Location location) {
- bufferOfLocations.add(location);
+ if(startSendingLocations) {
+ bufferOfLocations.add(location);
+ }
+ }
+
+ public int getLocationsSent() {
+ return locationsSent;
+ }
+
+ public int getBufferLocationsSize() {
+ return bufferOfLocations.size();
}
public void sendCoordinate(double lat, double lon) {
@@ -43,5 +99,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(command.indexOf(':') + 1);
+ 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;
+ }
+
}
diff --git a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
index bc0060a2b8..718eb7dc4f 100644
--- a/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
+++ b/OsmAnd/src/net/osmand/plus/osmo/SettingsOsMoActivity.java
@@ -1,34 +1,123 @@
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.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
-import android.provider.Settings;
+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 debugPref;
+ private Preference trackerId;
+ private CheckBoxPreference sendLocationsref;
@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));
-
- grp.addPreference(pref);
+ 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);
}
+ private void updateDebugPref() {
+ final OsMoPlugin plugin = OsMoPlugin.getEnabledPlugin(OsMoPlugin.class);
+ OsMoService service = plugin.getService();
+ OsMoTracker tracker = plugin.getTracker();
+ StringBuilder s = new StringBuilder();
+ 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 {
+ 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())).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());
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ 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);
+ }
+
+ @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() {
super.updateAllSettings();
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