Osmand Api in progress. Map markers fixes.

This commit is contained in:
Alexey Kulish 2016-03-15 19:58:25 +03:00
parent 969701adf3
commit 86b24520e5
10 changed files with 370 additions and 21 deletions

View file

@ -139,6 +139,14 @@
<data android:scheme="google.navigation" />
<data android:scheme="osmand.navigation" />
</intent-filter>
<!-- osmand api -->
<intent-filter>
<data android:scheme="osmand.api" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name="net.osmand.plus.audionotes.MediaRemoteControlReceiver">

View file

@ -6,7 +6,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.text.TextUtils;
import android.text.format.DateFormat;
@ -15,11 +14,14 @@ import android.util.TypedValue;
import android.view.View;
import android.view.ViewParent;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import android.widget.TextView;
import net.osmand.plus.R;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Date;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
@ -151,4 +153,24 @@ public class AndroidUtils {
public static boolean isValidEmail(CharSequence target) {
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
public static String getFileAsString(File file) {
try {
FileInputStream fin = new FileInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (sb.length() > 0) {
sb.append("\n");
}
sb.append(line);
}
reader.close();
fin.close();
return sb.toString();
} catch (Exception e) {
return null;
}
}
}

View file

@ -302,8 +302,8 @@ public class MapMarkersHelper {
pointDescription.setName(PointDescription.getSearchAddressStr(ctx));
}
if (colorIndex == -1) {
if (mapMarkers.size() > 0) {
colorIndex = (mapMarkers.get(0).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
if (sortedMapMarkers.size() > 0) {
colorIndex = (sortedMapMarkers.get(0).colorIndex + 1) % MAP_MARKERS_COLORS_COUNT;
} else {
colorIndex = 0;
}

View file

@ -81,6 +81,7 @@ import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.ExternalApiHelper;
import net.osmand.plus.helpers.GpxImportHelper;
import net.osmand.plus.helpers.WakeLockHelper;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
@ -557,6 +558,13 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents,
setIntent(null);
} else if ("google.navigation".equals(scheme) || "osmand.navigation".equals(scheme)) {
parseNavigationIntent(data);
} else if ("osmand.api".equals(scheme)) {
ExternalApiHelper apiHelper = new ExternalApiHelper(this);
Intent result = apiHelper.processApiRequest(intent);
setResult(apiHelper.getResultCode(), result);
if (apiHelper.needFinish()) {
finish();
}
}
}
}
@ -687,7 +695,7 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents,
getMyApplication().getTargetPointsHelper().navigateToPoint(new LatLon(lat, lon), false,
-1);
getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, false);
getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, false, true);
} catch (NumberFormatException e) {
AccessibleToast.makeText(this,
getString(R.string.navigation_intent_invalid, schemeSpecificPart),
@ -712,7 +720,7 @@ public class MapActivity extends AccessibleActivity implements DownloadEvents,
Location loc = new Location("map");
loc.setLatitude(mapView.getLatitude());
loc.setLongitude(mapView.getLongitude());
getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true);
getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
if (dashboardOnMap.isVisible()) {
dashboardOnMap.hideDashboard();
}

View file

@ -370,7 +370,7 @@ public class MapActivityActions implements DialogProvider {
bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
enterRoutePlanningModeGivenGpx(gpxFiles.get(0), from, fromName, useIntermediatePointsByDefault);
enterRoutePlanningModeGivenGpx(gpxFiles.get(0), from, fromName, useIntermediatePointsByDefault, true);
}
});
} else {
@ -392,7 +392,7 @@ public class MapActivityActions implements DialogProvider {
bld.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
enterRoutePlanningModeGivenGpx(gpxFiles.get(i), from, fromName, useIntermediatePointsByDefault);
enterRoutePlanningModeGivenGpx(gpxFiles.get(i), from, fromName, useIntermediatePointsByDefault, true);
}
});
}
@ -400,16 +400,17 @@ public class MapActivityActions implements DialogProvider {
bld.setNegativeButton(R.string.shared_string_no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
enterRoutePlanningModeGivenGpx(null, from, fromName, useIntermediatePointsByDefault);
enterRoutePlanningModeGivenGpx(null, from, fromName, useIntermediatePointsByDefault, true);
}
});
bld.show();
} else {
enterRoutePlanningModeGivenGpx(null, from, fromName, useIntermediatePointsByDefault);
enterRoutePlanningModeGivenGpx(null, from, fromName, useIntermediatePointsByDefault, true);
}
}
public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName, boolean useIntermediatePointsByDefault) {
public void enterRoutePlanningModeGivenGpx(GPXFile gpxFile, LatLon from, PointDescription fromName,
boolean useIntermediatePointsByDefault, boolean showDialog) {
settings.USE_INTERMEDIATE_POINTS_NAVIGATION.set(useIntermediatePointsByDefault);
OsmandApplication app = mapActivity.getMyApplication();
TargetPointsHelper targets = app.getTargetPointsHelper();
@ -431,7 +432,9 @@ public class MapActivityActions implements DialogProvider {
mapActivity.getMapViewTrackingUtilities().switchToRoutePlanningMode();
mapActivity.getMapView().refreshMap(true);
mapActivity.getMapLayers().getMapControlsLayer().showDialog();
if (showDialog) {
mapActivity.getMapLayers().getMapControlsLayer().showDialog();
}
if (targets.hasTooLongDistanceToNavigate()) {
app.showToastMessage(R.string.route_is_too_long);
}

View file

@ -1223,8 +1223,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|| visibleType == DashboardType.LIST_MENU
|| visibleType == DashboardType.ROUTE_PREFERENCES
|| visibleType == DashboardType.CONFIGURE_SCREEN
|| visibleType == DashboardType.MAP_MARKERS
|| visibleType == DashboardType.MAP_MARKERS_SELECTION;
|| (visibleType == DashboardType.MAP_MARKERS && mapMarkerDialogHelper.hasActiveMarkers())
|| (visibleType == DashboardType.MAP_MARKERS_SELECTION && mapMarkerDialogHelper.hasActiveMarkers());
}
private boolean isBackButtonVisible() {

View file

@ -53,7 +53,30 @@ public class ColorDialogs {
0xb48e2512
};
public static String[] paletteColorTags = new String[] {
"red",
"orange",
"yellow",
"lightgreen",
"green",
"lightblue",
"blue",
"purple",
"pink",
"brown"
};
public static int getColorByTag(String tag) {
String t = tag.toLowerCase();
for (int i = 0; i < paletteColorTags.length; i++) {
String colorTag = paletteColorTags[i];
if (colorTag.equals(t)) {
return pallette[i];
}
}
return 0;
}
public static void setupColorSpinner(Context ctx, int selectedColor, final Spinner colorSpinner,
final TIntArrayList colors) {
OnItemSelectedListener listener = new OnItemSelectedListener() {

View file

@ -0,0 +1,281 @@
package net.osmand.plus.helpers;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AlertDialog;
import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.util.Algorithms;
import java.io.ByteArrayInputStream;
import java.io.File;
public class ExternalApiHelper {
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ExternalApiHelper.class);
private static final String API_CMD_SHOW_GPX = "show_gpx";
private static final String API_CMD_NAVIGATE_GPX = "navigate_gpx";
private static final String API_CMD_CALC_ROUTE = "calc_route";
private static final String API_CMD_REC_AV_NOTE = "rec_av_note";
private static final String API_CMD_GET_INFO = "get_info";
private static final String API_CMD_ADD_FAVORITE = "add_favorite";
private static final String API_CMD_ADD_MAP_MARKER = "add_map_marker";
private static final String API_CMD_START_GPX_REC = "start_gpx_rec";
private static final String API_CMD_STOP_GPX_REC = "stop_gpx_rec";
private static final String API_CMD_SUBSCRIBE_VOICE_NOTIFICATIONS = "subscribe_voice_notifications";
private static final String PARAM_NAME = "name";
private static final String PARAM_DESC = "desc";
private static final String PARAM_CATEGORY = "category";
private static final String PARAM_LAT = "lat";
private static final String PARAM_LON = "lon";
private static final String PARAM_COLOR = "color";
private static final String PARAM_VISIBLE = "visible";
private static final String PARAM_PATH = "path";
private static final String PARAM_DATA = "data";
private static final int RESULT_CODE_OK = 0;
private static final int RESULT_CODE_ERROR_UNKNOWN = -1;
private static final int RESULT_CODE_ERROR_GPX_PLUGIN_INACTIVE = 10;
private static final int RESULT_CODE_ERROR_GPX_NOT_FOUND = 20;
private MapActivity mapActivity;
private int resultCode;
private boolean finish;
public int getResultCode() {
return resultCode;
}
public boolean needFinish() {
return finish;
}
public ExternalApiHelper(MapActivity mapActivity) {
this.mapActivity = mapActivity;
}
public Intent processApiRequest(Intent intent) {
Intent result = new Intent();
OsmandApplication app = (OsmandApplication) mapActivity.getApplication();
try {
/*
+ 1. Intent to show GPX file / start navigation with GPX
2. Intent to calculate route between points (passing profile mode) and immediately start navigation
3. Intent to request audio/video recording
4. Intent (with result?) Current location, ETA, distance to go, time to go on the route
+ 5. Intent to add Favorites / Markers
+ 6. Intent to start/stop recording GPX
Service:
8. Subscribe to voice notifications
// test marker
Uri uri = Uri.parse("osmand.api://add_map_marker?lat=45.610677&lon=34.368430&name=Marker");
// test favorite
Uri uri = Uri.parse("osmand.api://add_favorite?lat=45.610677&lon=34.368430&name=Favorite&desc=Description&category=test2&color=red&visible=true");
// test start gpx recording
Uri uri = Uri.parse("osmand.api://start_gpx_rec");
// test stop gpx recording
Uri uri = Uri.parse("osmand.api://stop_gpx_rec");
// test show gpx (path)
File gpx = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), "xxx.gpx");
Uri uri = Uri.parse("osmand.api://show_gpx?path=" + URLEncoder.encode(gpx.getAbsolutePath(), "UTF-8"));
Uri uri = Uri.parse("osmand.api://navigate_gpx?path=" + URLEncoder.encode(gpx.getAbsolutePath(), "UTF-8"));
// test show gpx (data)
Uri uri = Uri.parse("osmand.api://show_gpx");
Uri uri = Uri.parse("osmand.api://navigate_gpx");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra("data", AndroidUtils.getFileAsString(
new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), "xxx.gpx")));
*/
Uri uri = intent.getData();
String cmd = uri.getHost().toLowerCase();
if (API_CMD_SHOW_GPX.equals(cmd) || API_CMD_NAVIGATE_GPX.equals(cmd)) {
boolean navigate = API_CMD_NAVIGATE_GPX.equals(cmd);
String path = uri.getQueryParameter(PARAM_PATH);
GPXFile gpx = null;
if (path != null) {
File f = new File(path);
if (f.exists()) {
gpx = GPXUtilities.loadGPXFile(mapActivity, f);
}
} else if (intent.getStringExtra(PARAM_DATA) != null) {
String gpxStr = intent.getStringExtra(PARAM_DATA);
if (!Algorithms.isEmpty(gpxStr)) {
gpx = GPXUtilities.loadGPXFile(mapActivity, new ByteArrayInputStream(gpxStr.getBytes()));
}
} else {
resultCode = RESULT_CODE_ERROR_GPX_NOT_FOUND;
}
if (gpx != null) {
if (navigate) {
final RoutingHelper routingHelper = app.getRoutingHelper();
if (routingHelper.isFollowingMode()) {
final GPXFile gpxFile = gpx;
AlertDialog dlg = mapActivity.getMapActions().stopNavigationActionConfirm();
dlg.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (!routingHelper.isFollowingMode()) {
startNavigation(gpxFile);
}
}
});
} else {
startNavigation(gpx);
}
} else {
app.getSelectedGpxHelper().setGpxFileToDisplay(gpx);
}
resultCode = RESULT_CODE_OK;
} else {
resultCode = RESULT_CODE_ERROR_GPX_NOT_FOUND;
}
} else if (API_CMD_CALC_ROUTE.equals(cmd)) {
} else if (API_CMD_REC_AV_NOTE.equals(cmd)) {
} else if (API_CMD_GET_INFO.equals(cmd)) {
finish = true;
resultCode = RESULT_CODE_OK;
} else if (API_CMD_ADD_FAVORITE.equals(cmd)) {
String name = uri.getQueryParameter(PARAM_NAME);
String desc = uri.getQueryParameter(PARAM_DESC);
String category = uri.getQueryParameter(PARAM_CATEGORY);
double lat = Double.parseDouble(uri.getQueryParameter(PARAM_LAT));
double lon = Double.parseDouble(uri.getQueryParameter(PARAM_LON));
String colorTag = uri.getQueryParameter(PARAM_COLOR);
String visibleStr = uri.getQueryParameter(PARAM_VISIBLE);
if (name == null) {
name = "";
}
if (desc == null) {
desc = "";
}
if (category == null) {
category = "";
}
int color = 0;
if (!Algorithms.isEmpty(colorTag)) {
color = ColorDialogs.getColorByTag(colorTag);
if (color == 0) {
LOG.error("Wrong color tag: " + colorTag);
}
}
boolean visible = true;
if (!Algorithms.isEmpty(visibleStr)) {
visible = Boolean.parseBoolean(visibleStr);
}
FavouritePoint fav = new FavouritePoint(lat, lon, name, category);
fav.setDescription(desc);
fav.setColor(color);
fav.setVisible(visible);
FavouritesDbHelper helper = app.getFavorites();
helper.addFavourite(fav);
resultCode = RESULT_CODE_OK;
} else if (API_CMD_ADD_MAP_MARKER.equals(cmd)) {
double lat = Double.parseDouble(uri.getQueryParameter(PARAM_LAT));
double lon = Double.parseDouble(uri.getQueryParameter(PARAM_LON));
String name = uri.getQueryParameter(PARAM_NAME);
PointDescription pd = new PointDescription(
PointDescription.POINT_TYPE_MAP_MARKER, name != null ? name : "");
MapMarkersHelper markersHelper = app.getMapMarkersHelper();
markersHelper.addMapMarker(new LatLon(lat, lon), pd);
resultCode = RESULT_CODE_OK;
} else if (API_CMD_START_GPX_REC.equals(cmd)) {
OsmandMonitoringPlugin plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class);
if (plugin == null) {
resultCode = RESULT_CODE_ERROR_GPX_PLUGIN_INACTIVE;
} else {
plugin.startGPXMonitoring(null);
}
resultCode = RESULT_CODE_OK;
} else if (API_CMD_STOP_GPX_REC.equals(cmd)) {
OsmandMonitoringPlugin plugin = OsmandPlugin.getPlugin(OsmandMonitoringPlugin.class);
if (plugin == null) {
resultCode = RESULT_CODE_ERROR_GPX_PLUGIN_INACTIVE;
} else {
plugin.stopRecording();
}
resultCode = RESULT_CODE_OK;
} else if (API_CMD_SUBSCRIBE_VOICE_NOTIFICATIONS.equals(cmd)) {
}
} catch (Exception e) {
LOG.error("Error processApiRequest:", e);
resultCode = RESULT_CODE_ERROR_UNKNOWN;
}
return result;
}
private void startNavigation(GPXFile gpx) {
OsmandApplication app = mapActivity.getMyApplication();
RoutingHelper routingHelper = app.getRoutingHelper();
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpx, null, null, false, false);
if (!app.getTargetPointsHelper().checkPointToNavigateShort()) {
mapActivity.getMapLayers().getMapControlsLayer().getMapRouteInfoMenu().show();
} else {
app.getSettings().APPLICATION_MODE.set(routingHelper.getAppMode());
mapActivity.getMapViewTrackingUtilities().backToLocationImpl();
app.getSettings().FOLLOW_THE_ROUTE.set(true);
routingHelper.setFollowingMode(true);
routingHelper.setRoutePlanningMode(false);
mapActivity.getMapViewTrackingUtilities().switchToRoutePlanningMode();
app.getRoutingHelper().notifyIfRouteIsCalculated();
routingHelper.setCurrentLocation(app.getLocationProvider().getLastKnownLocation(), false);
}
}
}

View file

@ -99,6 +99,10 @@ public class MapMarkerDialogHelper {
return selectionMode;
}
public boolean hasActiveMarkers() {
return markersHelper.getActiveMapMarkers().size() > 0;
}
public void setSelectionMode(boolean selectionMode) {
this.selectionMode = selectionMode;
}
@ -341,7 +345,7 @@ public class MapMarkerDialogHelper {
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
MenuItem item;
item = optionsMenu.getMenu().add(R.string.shared_string_clear)
.setIcon(iconsCache.getContentIcon(R.drawable.ic_action_delete_dark, !nightMode));
.setIcon(iconsCache.getContentIcon(R.drawable.ic_action_delete_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
@ -369,7 +373,7 @@ public class MapMarkerDialogHelper {
if (!sorted) {
item = optionsMenu.getMenu().add(R.string.shared_string_reverse_order).setIcon(
iconsCache.getContentIcon(R.drawable.ic_action_undo_dark, !nightMode));
iconsCache.getContentIcon(R.drawable.ic_action_undo_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
@ -385,7 +389,7 @@ public class MapMarkerDialogHelper {
}
item = optionsMenu.getMenu().add(R.string.shared_string_save_as_gpx).setIcon(
iconsCache.getContentIcon(R.drawable.ic_action_save, !nightMode));
iconsCache.getContentIcon(R.drawable.ic_action_save));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {

View file

@ -472,7 +472,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
latLon.getLongitude(), getPointDescriptionForTarget());
} else if (targets.getIntermediatePoints().isEmpty()) {
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true);
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
close();
} else {
Builder bld = new AlertDialog.Builder(mapActivity);
@ -494,11 +494,11 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
if (defaultVls[0] == 0) {
targets.removeAllWayPoints(false, true);
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true);
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
close();
} else {
targets.navigateToPoint(latLon, true, -1, getPointDescriptionForTarget());
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true);
mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(null, null, null, true, true);
close();
}
}