Merge branch 'master' of https://github.com/dubrovskip/Osmand
This commit is contained in:
commit
f254dedb18
23 changed files with 1156 additions and 262 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>>();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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()){
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
283
OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
Normal file
283
OsmAnd/src/net/osmand/plus/osmo/OsMoGroups.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
9
OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java
Normal file
9
OsmAnd/src/net/osmand/plus/osmo/OsMoReactor.java
Normal 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);
|
||||
|
||||
}
|
6
OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java
Normal file
6
OsmAnd/src/net/osmand/plus/osmo/OsMoSender.java
Normal file
|
@ -0,0 +1,6 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
public interface OsMoSender {
|
||||
|
||||
public String nextSendCommand(OsMoThread tracker);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue