Enable background service in navigation mode

This commit is contained in:
Victor Shcherb 2012-09-23 18:07:14 +02:00
parent 506c2bd41f
commit d38407e11a
8 changed files with 105 additions and 90 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -19,6 +19,7 @@
\n\t* better UI finish (icons)
\n\t* lots of bug fixes
</string>
<string name="no_route">No route</string>
<string name="delete_target_point">Remove target point</string>
<string name="target_point">Target point %1$s</string>
<string name="intermediate_point">Waypoint %1$s</string>

View file

@ -35,6 +35,7 @@ public class NavigationService extends Service implements LocationListener {
}
private final static int NOTIFICATION_SERVICE_ID = 1;
public final static String OSMAND_STOP_SERVICE_ACTION = "OSMAND_STOP_SERVICE_ACTION"; //$NON-NLS-1$
public final static String NAVIGATION_START_SERVICE_PARAM = "NAVIGATION_START_SERVICE_PARAM";
private static final int LOST_LOCATION_MSG_ID = 10;
private static final long LOST_LOCATION_CHECK_DELAY = 20000;
@ -55,6 +56,7 @@ public class NavigationService extends Service implements LocationListener {
private PendingIntent pendingIntent;
private BroadcastReceiver broadcastReceiver;
private LiveMonitoringHelper liveMonitoringHelper;
private boolean startedForNavigation;
@Override
public IBinder onBind(Intent intent) {
@ -85,14 +87,20 @@ public class NavigationService extends Service implements LocationListener {
return serviceOffProvider;
}
public boolean startedForNavigation(){
return startedForNavigation;
}
@Override
public void onCreate() {
super.onCreate();
// initializing variables
setForeground(true);
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
settings = ((OsmandApplication) getApplication()).getSettings();
serviceOffInterval = settings.SERVICE_OFF_INTERVAL.get();
startedForNavigation = intent.getBooleanExtra(NAVIGATION_START_SERVICE_PARAM, false);
if (startedForNavigation) {
serviceOffInterval = 0;
} else {
serviceOffInterval = settings.SERVICE_OFF_INTERVAL.get();
}
// use only gps provider
serviceOffProvider = LocationManager.GPS_PROVIDER;
serviceError = serviceOffInterval / 5;
@ -122,23 +130,33 @@ public class NavigationService extends Service implements LocationListener {
}
// registering icon at top level
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
NavigationService.this.stopSelf();
}
// Leave icon visible even for navigation for proper testing
// if (!startedForNavigation) {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
NavigationService.this.stopSelf();
}
};
registerReceiver(broadcastReceiver, new IntentFilter(OSMAND_STOP_SERVICE_ACTION));
Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION);
Notification notification = new Notification(R.drawable.bgs_icon, "", //$NON-NLS-1$
System.currentTimeMillis());
notification.flags = Notification.FLAG_NO_CLEAR;
notification.setLatestEventInfo(this, Version.getAppName(this),
getString(R.string.service_stop_background_service), PendingIntent.getBroadcast(this, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_SERVICE_ID, notification);
};
registerReceiver(broadcastReceiver, new IntentFilter(OSMAND_STOP_SERVICE_ACTION));
Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION);
Notification notification = new Notification(R.drawable.bgs_icon, "", //$NON-NLS-1$
System.currentTimeMillis());
notification.flags = Notification.FLAG_NO_CLEAR;
notification.setLatestEventInfo(this, Version.getAppName(this), getString(R.string.service_stop_background_service),
PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT));
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_SERVICE_ID, notification);
// }
return START_REDELIVER_INTENT;
}
@Override
public void onCreate() {
super.onCreate();
// initializing variables
setForeground(true);
}
private boolean isContinuous(){

View file

@ -86,7 +86,7 @@ public class OsmandApplication extends Application {
long timeToStart = System.currentTimeMillis();
osmandSettings = createOsmandSettingsInstance();
routingHelper = new RoutingHelper(osmandSettings, this, player);
routingHelper = new RoutingHelper(this, player);
manager = new ResourceManager(this);
daynightHelper = new DayNightHelper(this);
bidforfix = new BidForFixHelper("osmand.net", getString(R.string.default_buttons_support), getString(R.string.default_buttons_cancel));

View file

@ -426,9 +426,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
if (endPoint == null) {
notRestoreRoutingMode();
} else {
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(endPoint, intermediates, startPoint, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
followRoute(settings.getApplicationMode(), endPoint, intermediates, startPoint, gpxRoute);
}
}
};
@ -944,6 +942,26 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe
settings.getIntermediatePoints(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute());
}
}
public void followRoute(ApplicationMode appMode, LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation, GPXRouteParams gpxRoute){
// change global settings
// Do not overwrite PREV_APPLICATION_MODE if already navigating
if (!routingHelper.isFollowingMode()) {
settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get());
}
boolean changed = settings.APPLICATION_MODE.set(appMode);
if (changed) {
updateApplicationModeSettings();
}
getMapView().refreshMap(changed);
settings.FOLLOW_THE_ROUTE.set(true);
if(gpxRoute == null) {
settings.FOLLOW_THE_GPX_ROUTE.set(null);
}
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(finalLocation, intermediatePoints, currentLocation, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this);
}
public void navigateToPoint(LatLon point, boolean updateRoute, int intermediate){
if(point != null){

View file

@ -469,10 +469,6 @@ public class MapActivityActions implements DialogProvider {
return;
}
ApplicationMode mode = getAppMode(buttons, settings);
// Do not overwrite PREV_APPLICATION_MODE if already navigating
if (!routingHelper.isFollowingMode()) {
settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get());
}
routingHelper.setAppMode(mode);
settings.FOLLOW_THE_ROUTE.set(false);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
@ -502,24 +498,9 @@ public class MapActivityActions implements DialogProvider {
AccessibleToast.makeText(mapActivity, R.string.route_updated_loc_found, Toast.LENGTH_LONG).show();
}
ApplicationMode mode = getAppMode(buttons, settings);
// change global settings
// Do not overwrite PREV_APPLICATION_MODE if already navigating
if (!routingHelper.isFollowingMode()) {
settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get());
}
boolean changed = settings.APPLICATION_MODE.set(mode);
if (changed) {
mapActivity.updateApplicationModeSettings();
mapActivity.getMapView().refreshMap(true);
}
routingHelper.setAppMode(mode);
settings.FOLLOW_THE_ROUTE.set(true);
settings.FOLLOW_THE_GPX_ROUTE.set(null);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(mapActivity.getPointToNavigate(), mapActivity.getIntermediatePoints(),
current, null);
dialog.dismiss();
getMyApplication().showDialogInitializingCommandPlayer(mapActivity);
mapActivity.followRoute(mode, mapActivity.getPointToNavigate(), mapActivity.getIntermediatePoints(),
current, null);
}
};
@ -533,15 +514,12 @@ public class MapActivityActions implements DialogProvider {
builder.setView(view);
builder.setTitle(R.string.get_directions);
builder.setPositiveButton(R.string.follow, followCall);
builder.setNeutralButton(R.string.only_show, onlyShowCall);
if (gpxRouteEnabled) {
builder.setPositiveButton(R.string.follow, followCall);
builder.setNeutralButton(R.string.gpx_navigation, useGpxNavigation);
builder.setNegativeButton(R.string.only_show, onlyShowCall);
builder.setNegativeButton(R.string.gpx_navigation, useGpxNavigation);
} else {
// view.findViewById(R.id.TextView).setVisibility(View.GONE);
builder.setPositiveButton(R.string.follow, followCall);
builder.setNeutralButton(R.string.only_show, onlyShowCall);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.setNegativeButton(R.string.no_route, null);
}
builder.show();
}
@ -553,7 +531,6 @@ public class MapActivityActions implements DialogProvider {
public void navigateUsingGPX(final ApplicationMode appMode) {
final LatLon endForRouting = mapActivity.getPointToNavigate();
final MapActivityLayers mapLayers = mapActivity.getMapLayers();
final RoutingHelper routingHelper = mapActivity.getRoutingHelper();
mapLayers.selectGPXFileLayer(new CallbackWithObject<GPXFile>() {
@Override
@ -597,23 +574,10 @@ public class MapActivityActions implements DialogProvider {
mapLayers.getNavigationLayer().setPointToNavigate(point, new ArrayList<LatLon>());
}
}
// change global settings
// Do not overwrite PREV_APPLICATION_MODE if already navigating
if (!routingHelper.isFollowingMode()) {
settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get());
}
boolean changed = settings.APPLICATION_MODE.set(appMode);
if (changed) {
mapActivity.updateApplicationModeSettings();
}
mapActivity.getMapView().refreshMap(changed);
if(endPoint != null){
settings.FOLLOW_THE_ROUTE.set(true);
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);
routingHelper.setFollowingMode(true);
routingHelper.setFinalAndCurrentLocation(endPoint,
mapActivity.followRoute(appMode, endPoint,
new ArrayList<LatLon>(), startForRouting, gpxRoute);
getMyApplication().showDialogInitializingCommandPlayer(mapActivity);
settings.FOLLOW_THE_GPX_ROUTE.set(result.path);
}
}
});

View file

@ -10,6 +10,8 @@ import net.osmand.OsmAndFormatter;
import net.osmand.access.AccessibleToast;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.osmand.plus.NavigationService;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.OsmandSettings.MetricsConstants;
@ -21,6 +23,7 @@ import net.osmand.plus.voice.CommandPlayer;
import net.osmand.router.Interruptable;
import net.osmand.router.RouteSegmentResult;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Handler;
import android.widget.Toast;
@ -40,7 +43,7 @@ public class RoutingHelper {
private List<IRouteInformationListener> listeners = new ArrayList<IRouteInformationListener>();
private Context context;
private OsmandApplication app;
private boolean isFollowingMode = false;
@ -74,9 +77,8 @@ public class RoutingHelper {
}
public RoutingHelper(OsmandSettings settings, Context context, CommandPlayer player){
this.settings = settings;
this.context = context;
public RoutingHelper(OsmandApplication context, CommandPlayer player){
this.app = context;
voiceRouter = new VoiceRouter(this, player);
uiHandler = new Handler();
}
@ -84,11 +86,22 @@ public class RoutingHelper {
public boolean isFollowingMode() {
return isFollowingMode;
}
public void setFollowingMode(boolean isFollowingMode) {
this.isFollowingMode = isFollowingMode;
}
public void setFollowingMode(boolean follow) {
isFollowingMode = follow;
Intent serviceIntent = new Intent(app, NavigationService.class);
if(follow) {
if(app.getNavigationService() == null) {
serviceIntent.putExtra(NavigationService.NAVIGATION_START_SERVICE_PARAM, true);
app.startService(serviceIntent);
}
} else {
if(app.getNavigationService() != null && app.getNavigationService().startedForNavigation()) {
app.stopService(serviceIntent);
}
}
}
public synchronized void setFinalAndCurrentLocation(LatLon finalLocation, List<LatLon> intermediatePoints, Location currentLocation, GPXRouteParams gpxRoute){
@ -121,7 +134,7 @@ public class RoutingHelper {
settings.FOLLOW_THE_GPX_ROUTE.set(null);
// clear last fixed location
this.lastProjection = null;
this.isFollowingMode = false;
setFollowingMode(false);
}
}
@ -340,7 +353,7 @@ public class RoutingHelper {
// 2. check if intermediate found
if(route.getIntermediatePointsToPass() > 0 && route.getDistanceToNextIntermediate(lastFixedLocation) < posTolerance) {
showMessage(context.getString(R.string.arrived_at_intermediate_point));
showMessage(app.getString(R.string.arrived_at_intermediate_point));
voiceRouter.arrivedIntermediatePoint();
route.passIntermediatePoint();
int toDel = settings.getIntermediatePoints().size() - route.getIntermediatePointsToPass();
@ -356,7 +369,7 @@ public class RoutingHelper {
// 3. check if destination found
Location lastPoint = routeNodes.get(routeNodes.size() - 1);
if (currentRoute > routeNodes.size() - 3 && currentLocation.distanceTo(lastPoint) < posTolerance * 1.2) {
showMessage(context.getString(R.string.arrived_at_destination));
showMessage(app.getString(R.string.arrived_at_destination));
voiceRouter.arrivedDestinationPoint();
clearCurrentRoute(null, null);
return true;
@ -478,7 +491,7 @@ public class RoutingHelper {
int dist = getLeftDistance();
int hours = getLeftTime() / (60 * 60);
int minutes = (getLeftTime() / 60) % 60;
return context.getString(R.string.route_general_information, OsmAndFormatter.getFormattedDistance(dist, context),
return app.getString(R.string.route_general_information, OsmAndFormatter.getFormattedDistance(dist, app),
hours, minutes);
}
@ -588,7 +601,7 @@ public class RoutingHelper {
public void run() {
boolean leftSide = settings.LEFT_SIDE_NAVIGATION.get();
boolean fastRoute = settings.FAST_ROUTE_MODE.get();
RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, context, gpxRoute, previousRoute, fastRoute,
RouteCalculationResult res = provider.calculateRouteImpl(start, end, intermediates, mode, service, app, gpxRoute, previousRoute, fastRoute,
leftSide, this);
if (interrupted) {
currentRunningJob = null;
@ -606,16 +619,16 @@ public class RoutingHelper {
}
if (res.isCalculated()) {
showMessage(context.getString(R.string.new_route_calculated_dist)
+ ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), context)); //$NON-NLS-1$
showMessage(app.getString(R.string.new_route_calculated_dist)
+ ": " + OsmAndFormatter.getFormattedDistance(res.getWholeDistance(), app)); //$NON-NLS-1$
} else if (service != RouteService.OSMAND && !settings.isInternetConnectionAvailable()) {
showMessage(context.getString(R.string.error_calculating_route)
+ ":\n" + context.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$
showMessage(app.getString(R.string.error_calculating_route)
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route), Toast.LENGTH_LONG); //$NON-NLS-1$
} else {
if (res.getErrorMessage() != null) {
showMessage(context.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage(), Toast.LENGTH_LONG); //$NON-NLS-1$
showMessage(app.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage(), Toast.LENGTH_LONG); //$NON-NLS-1$
} else {
showMessage(context.getString(R.string.empty_route_calculated), Toast.LENGTH_LONG);
showMessage(app.getString(R.string.empty_route_calculated), Toast.LENGTH_LONG);
}
}
lastTimeEvaluatedRoute = System.currentTimeMillis();
@ -647,7 +660,7 @@ public class RoutingHelper {
uiHandler.post(new Runnable() {
@Override
public void run() {
AccessibleToast.makeText(context, msg, length).show();
AccessibleToast.makeText(app, msg, length).show();
}
});
}
@ -662,7 +675,7 @@ public class RoutingHelper {
}
protected Context getContext() {
return context;
return app;
}
@ -670,4 +683,5 @@ public class RoutingHelper {
return provider.createOsmandRouterGPX(route);
}
}