This commit is contained in:
unknown 2014-05-22 11:10:22 +03:00
commit f254dedb18
23 changed files with 1156 additions and 262 deletions

View file

@ -559,7 +559,7 @@
<string name="search_history_street">Rue :\n{0}\n{1}</string>
<string name="search_history_int_streets">Intersection :\n{0} x {1} dans {2}</string>
<string name="search_history_building">Bâtiment :\n{0} {1}\n{2}</string>
<string name="favorite">Favori</string>
<string name="favorite">Favori </string>
<string name="clear_all">Effacer tout</string>
<string name="history">Historique</string>
<string name="uploading_data">Envoi des données…</string>
@ -601,7 +601,7 @@
<string name="opening_changeset">Ouverture des modifications…</string>
<string name="closing_changeset">Fermeture des modifications…</string>
<string name="commiting_node">Envoi des nœuds…</string>
<string name="loading_poi_obj">Chargement des Points d\'Intérêts…</string>
<string name="loading_poi_obj">Chargement des Points d\'intérêts…</string>
<string name="auth_failed">Autorisation refusée</string>
<string name="failed_op">Échec</string>
<string name="converting_names">Convertir les noms en anglais…</string>
@ -909,14 +909,14 @@
<string name="gpxup_private">Privé</string>
<string name="osmand_parking_event">Récupérer votre véhicule du parking</string>
<string name="osmand_parking_warning">Avertissement</string>
<string name="osmand_parking_warning_text">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.</string>
<string name="osmand_parking_warning_text">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.</string>
<string name="osmand_parking_time_limit_title">Donner un temps limite de stationnement</string>
<string name="osmand_parking_delete_confirm">Voulez-vous supprimer l\'emplacement de stationnement du véhicule ?</string>
<string name="osmand_parking_delete">Supprimer un emplacement de stationnement</string>
<string name="osmand_parking_choose_type">Choisir le type de stationnement</string>
<string name="osmand_parking_lim_text">Temps limité</string>
<string name="osmand_parking_no_lim_text">Temps illimité</string>
<string name="osmand_parking_add_event">Ajouter une notification dans l\'Agenda</string>
<string name="osmand_parking_add_event">Ajouter une notification dans l\'agenda</string>
<string name="osmand_parking_time_limit">Stationnement avec limite de temps</string>
<string name="osmand_parking_time_no_limit">Stationnement sans limite de temps</string>
<string name="osmand_parking_position_description">La position de votre véhicule. %1$s</string>
@ -1093,7 +1093,7 @@
<string name="no_buildings_found">Aucun numéro de bâtiment trouvé</string>
<string name="search_villages_and_postcodes">Rechercher les villages et les codes postaux</string>
<string name="route_descr_lat_lon">Lat %1$.3f lon %2$.3f</string>
<string name="route_descr_current_location">la position actuelle</string>
<string name="route_descr_current_location">La position actuelle</string>
<string name="map_widget_max_speed">Limite de vitesse</string>
@ -1281,7 +1281,7 @@
<string name="clear_destination">Effacer la destination</string>
<string name="other_location">Autre</string>
<string name="files_limit">Il reste %1$d fichiers</string>
<string name="available_downloads_left">Reste %1$d fichiers à télécharger</string>
<string name="available_downloads_left">Vous pouvez encore télécharger %1$d fichier(s).</string>
<string name="install_paid">Version complète</string>
<string name="use_magnetic_sensor_descr">Utiliser le magnétomètre pour déterminer l\'orientation de la boussole au lieu du capteur d\'orientation</string>
<string name="use_magnetic_sensor">Utiliser le magnétomètre (boussole)</string>
@ -1472,10 +1472,10 @@
<string name="routing_attr_avoid_motorway_description">Éviter les autoroutes</string>
<string name="routing_attr_weight_name">Poids</string>
<string name="routing_attr_weight_description">Spécifier la limite de poids</string>
<string name="select_gpx">Sélectionner GPX </string>
<string name="select_gpx">Sélectionner GPX…</string>
<string name="route_descr_select_destination">Définir la destination</string>
<string name="route_descr_select_on_map">Définir sur la carte </string>
<string name="route_descr_favorite">Favori </string>
<string name="route_descr_select_on_map">Définir sur la carte…</string>
<string name="route_descr_favorite">Favori…</string>
<string name="route_preferences">Préférences d\'itinéraire</string>
<string name="route_info">Informations sur l\'itinéraire</string>
<string name="keep_and_add_destination_point">Ajouter comme destination</string>
@ -1551,18 +1551,22 @@
<string name="interrupt_music_descr">Interrompre la musique lors des annonces</string>
<string name="interrupt_music">Interrompre la musique</string>
<string name="share_route_as_gpx">Partager l\'itinéraire au format GPX</string>
<string name="share_route_subject">Itinéraire partagé via OsmAnd</string>
<string name="share_route_subject">Itinéraire partagé via OsmAnd</string>
<string name="osmo_settings_uuid">Identifiant unique de l\'appareil</string>
<string name="osmo_settings_descr">Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi</string>
<string name="osmo_plugin_description">OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi</string>
<string name="osmo_plugin_name">OSMo (suivi en temps réel)</string>
<string name="osmo_settings">OSMo</string>
<string name="keep_informing_never">Jamais</string>
<string name="keep_informing_descr">Annoncer les instructions de navigation à intervalles réguliers</string>
<string name="keep_informing">Répéter les instructions de navigation</string>
<string name="navigation_intent_invalid">Format invalide : %s</string>
<string name="osmo_settings_descr">Voir la clé unique d\'enregistrement de l\'appareil et les autres paramètres spécifiques de suivi</string>
<string name="osmo_plugin_description">OpenStreetMap-Monitoring - Suivi en temps réel avec de nombreuses fonctionnalités de contrôle à distance http://osmo.mobi</string>
<string name="osmo_plugin_name">OSMo (suivi en temps réel)</string>
<string name="osmo_settings">OSMo</string>
<string name="osmo_register_device">Enregistrement de l\'appareil…</string>
<string name="osmo_io_error">Problème de connection OSMo : </string>
<string name="osmo_mode_on">Arrêter\nOSMo</string>
<string name="osmo_mode_off">Démarrer\nOSMo</string>
<string name="keep_informing_never">Jamais</string>
<string name="keep_informing_descr">Annoncer les instructions de navigation à intervalles réguliers</string>
<string name="keep_informing">Répéter les instructions de navigation</string>
<string name="navigation_intent_invalid">Format invalide : %s</string>
<string name="arrival_distance">Annonce de l\'arrivée</string>
<string name="arrival_distance_descr">Choisir à quel moment est annoncée l\'arrivée à destination</string>
<string name="arrival_distance_descr">Choisir à quel moment est annoncée l\'arrivée à destination</string>
<string-array name="arrival_distance_factors">
<item>Précoce</item>
<item>Normale</item>

View file

@ -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
-->
<string name="osmo_io_error">OSMo connection problem : </string>
<string name="osmo_mode_on">Stop OSMo</string>
<string name="osmo_mode_off">Start OSMo</string>
<string name="osmo_auto_send_locations_descr">Automatically start tracker session and send locations after application startup</string>
<string name="osmo_auto_send_locations">Automatically start tracker session</string>
<string name="osmo_tracker_id">Personal tracker id</string>
<string name="osmo_tracker_id_descr">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.</string>
<string name="osmo_session_token">Session token : %1$s</string>
<string name="osmo_auth_pending">Waiting for authorization...</string>
<string name="osmo_locations_sent">Locations sent %1$d (in buffer %2$d) </string>
<string name="osmo_conn_successfull">Connection established : %1$s </string>
<string name="osmo_io_error">OsMo connection problem : </string>
<string name="osmo_settings_uuid">Unique device id</string>
<string name="osmo_settings_descr">View unique device registration key and other monitoring specific settings </string>
<string name="osmo_settings">OSMo (OpenStreetMap-Monitoring)</string>
<string name="tip_recent_changes_1_8_alpha">Changes in 1.8:
* Calculate route between route points of GPX track
* Changed layout of countries for downloads (support local names search)
</string>
<string name="use_points_as_intermediates">Calculate route between points</string>
<string name="osmo_mode_restart">Restart OsMo session</string>
<string name="osmo_mode_on">Stop OsMo session</string>
<string name="osmo_mode_off">Start OsMo session</string>
<string name="osmo_settings_debug">Debug information</string>
<string name="osmo_settings_descr">Configure monitoring settings and setup personal monitoring channel</string>
<string name="osmo_settings">OsMo (OpenStreetMap-Monitoring)</string>
<string name="osmo_plugin_description">OpenStreetMap-Monitoring - Advanced Live Monitoring with lots of features for remote control http://osmo.mobi</string>
<string name="osmo_plugin_name">OSMo (Advanced Live Monitoring)</string>
<string name="osmo_settings">OSMo</string>
<string name="osmo_plugin_name">OsMo (Advanced Live Monitoring)</string>
<string name="osmo_settings">OsMo</string>
<string name="always_center_position_on_map">Display position always in center</string>
<string name="voice_pref_title">Voice</string>
<string name="misc_pref_title">Miscallenious</string>
@ -1441,6 +1457,8 @@ Afghanistan, Albania, Algeria, Andorra, Angola, Anguilla, Antigua and Barbuda, A
<string name="no_fav_to_save">No favorite points to save</string>
<string name="import_fav">Import</string>
<string name="export_fav">Export</string>
<string name="share_fav">Share</string>
<string name="share_fav_subject">Favourites shared via OsmAnd</string>
<string name="error_occurred_loading_gpx">Error occurred while loading GPX</string>
<string name="send_report">Send report</string>
<string name="none_region_found">No offline data for regions found on SD card. Download regions from the Internet.</string>

View file

@ -8,9 +8,9 @@
<CheckBoxPreference android:summary="@string/use_english_names_descr" android:title="@string/use_english_names"
android:key="use_english_names"></CheckBoxPreference>
<ListPreference android:key="default_driving_region" android:title="@string/driving_region" android:summary="@string/driving_region_descr"></ListPreference>
<!--
<ListPreference android:key="default_metric_system" android:title="@string/unit_of_length" android:summary="@string/unit_of_length_descr"></ListPreference>
-->
<ListPreference android:key="default_metric_system" android:title="@string/unit_of_length" android:summary="@string/unit_of_length_descr"></ListPreference>
</PreferenceCategory>
<PreferenceCategory android:title="@string/voice_pref_title" android:key="voice">
<ListPreference android:title="@string/voice_provider" android:key="voice_provider" android:summary="@string/voice_provider_descr"></ListPreference>

View file

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

View file

@ -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<List<WptPt>> tpoints = new ArrayList<List<WptPt>>();

View file

@ -632,7 +632,8 @@ public class OsmandSettings {
public final OsmandPreference<DrivingRegion> DRIVING_REGION = new EnumIntPreference<DrivingRegion>(
"default_driving_region", DrivingRegion.EUROPE_ASIA, DrivingRegion.values()) {
protected boolean setValue(Object prefs, DrivingRegion val) {
((CommonPreference<MetricsConstants>)METRIC_SYSTEM).cachedValue = null;
//((CommonPreference<MetricsConstants>)METRIC_SYSTEM).cachedValue = null;
((CommonPreference<MetricsConstants>)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<MetricsConstants> METRIC_SYSTEM = new EnumIntPreference<MetricsConstants>(
"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<Boolean> SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", true).makeProfile().cache();
public final OsmandPreference<Boolean> SPEAK_SPEED_LIMIT = new BooleanPreference("speak_speed_limit", true).makeProfile().cache();
public final OsmandPreference<Boolean> ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache();
public final OsmandPreference<Boolean> SPEAK_GPX_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache();
public final OsmandPreference<Boolean> CALC_GPX_ROUTE = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache();
public final OsmandPreference<Boolean> GPX_ROUTE_CALC_OSMAND_PARTS = new BooleanPreference("gpx_routing_calculate_osmand_route", true).makeGlobal().cache();
public final OsmandPreference<Boolean> GPX_CALCULATE_RTEPT = new BooleanPreference("gpx_routing_calculate_rtept", true).makeGlobal().cache();
public final OsmandPreference<Boolean> GPX_SPEAK_WPT = new BooleanPreference("speak_gpx_wpt", true).makeGlobal().cache();
public final OsmandPreference<Boolean> GPX_ROUTE_CALC = new BooleanPreference("calc_gpx_route", false).makeGlobal().cache();
@ -824,6 +826,12 @@ public class OsmandSettings {
public final OsmandPreference<String> MAP_INFO_CONTROLS = new StringPreference("map_info_controls", "").makeProfile();
public final OsmandPreference<String> OSMO_DEVICE_KEY = new StringPreference("osmo_device_token", "").makeGlobal();
public final OsmandPreference<Boolean> OSMO_AUTO_SEND_LOCATIONS = new BooleanPreference("osmo_automatically_send_locations", false).makeGlobal();
public final OsmandPreference<String> OSMO_GROUPS = new StringPreference("osmo_groups", "{}").makeGlobal();
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<Boolean> 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<Integer> SEARCH_TAB =
new IntPreference("SEARCH_TAB", 0).makeGlobal().cache();
public final CommonPreference<Integer> OSMAND_THEME =
new IntPreference("osmand_theme", OSMAND_DARK_THEME).makeGlobal().cache();

View file

@ -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<FavouritePoint> favoritesToDelete = new LinkedHashSet<FavouritePoint>();
private Set<String> groupsToDelete = new LinkedHashSet<String>();
private Comparator<FavouritePoint> 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<Void, Void, GPXFile> exportTask = new AsyncTask<Void, Void, GPXFile>() {
@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<String, List<FavouritePoint>> sourceFavoriteGroups;
Map<String, List<FavouritePoint>> favoriteGroups = new LinkedHashMap<String, List<FavouritePoint>>();
List<String> groups = new ArrayList<String>();
public void setFavoriteGroups(Map<String, List<FavouritePoint>> favoriteGroups) {
this.sourceFavoriteGroups = favoriteGroups;
synchronizeGroups();
}
public void sort(Comparator<FavouritePoint> comparator) {
for(List<FavouritePoint> 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()){

View file

@ -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<Location> ps = params.getPoints();
mapActivity.getRoutingHelper().setGpxParams(params);
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);

View file

@ -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<entries.length; i++){
// entries[i] = mvls[i].toHumanString(getMyApplication());
// }
// registerListPreference(settings.METRIC_SYSTEM, screen, entries, mvls);
MetricsConstants[] mvls = MetricsConstants.values();
entries = new String[mvls.length];
for(int i=0; i<entries.length; i++){
entries[i] = mvls[i].toHumanString(getMyApplication());
}
registerListPreference(settings.METRIC_SYSTEM, screen, entries, mvls);
String incompleteSuffix = " (" + getString(R.string.incomplete_locale) + ")";
//getResources().getAssets().getLocales();

View file

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

View file

@ -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<TabInfo> mTabs = new ArrayList<TabInfo>();
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);

View file

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

View file

@ -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<String, OsMoGroup> groups = new ConcurrentHashMap<String, OsMoGroup>();
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<String, OsMoUser> users = new ConcurrentHashMap<String, OsMoGroups.OsMoUser>();
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<OsMoMessage> messages = new ArrayList<OsMoMessage>();
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<String> toDelete = new HashSet<String>(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);
}
}

View file

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

View file

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

View file

@ -0,0 +1,6 @@
package net.osmand.plus.osmo;
public interface OsMoSender {
public String nextSendCommand(OsMoThread tracker);
}

View file

@ -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<OsMoSender> listSenders = new java.util.concurrent.CopyOnWriteArrayList<OsMoSender>();
private List<OsMoReactor> listReactors = new java.util.concurrent.CopyOnWriteArrayList<OsMoReactor>();
private ConcurrentLinkedQueue<String> commands = new ConcurrentLinkedQueue<String>();
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<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(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<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(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;
}
}

View file

@ -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<OsMoSender> listSenders;
private List<OsMoReactor> 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<String> queueOfMessages = new LinkedList<String>();
public OsMoThread(List<OsMoSender> listSenders, List<OsMoReactor> listReactors) {
public OsMoThread(OsMoService service, List<OsMoSender> listSenders, List<OsMoReactor> 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<String, Object> 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<Entry<String, Object>> it = params.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object> 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;
}
}
}

View file

@ -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<Location> bufferOfLocations = new LinkedList<Location>();
import org.json.JSONObject;
public class OsMoTracker implements OsMoSender, OsMoReactor {
private ConcurrentLinkedQueue<Location> bufferOfLocations = new ConcurrentLinkedQueue<Location>();
private Map<String, Location> otherLocations = new ConcurrentHashMap<String, Location>();
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;
}
}

View file

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

View file

@ -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<Location> 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<Location> intermediates = gpxParams.points;
return calculateOsmAndRouteWithIntermediatePoints(routeParams, intermediates);
}
List<Location> 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<Location> 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<LatLon>();
for(Location w : intermediates) {
rp.intermediates.add(new LatLon(w.getLatitude(), w.getLongitude()));
}
return findVectorMapsRoute(rp, false);
}
private List<RouteDirectionInfo> calcDirections(int[] startI, int[] endI,
final List<RouteDirectionInfo> inputDirections) {
List<RouteDirectionInfo> directions = new ArrayList<RouteDirectionInfo>();

View file

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

View file

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