Skip to content

Commit

Permalink
Refactor navigation service foreground mode
Browse files Browse the repository at this point in the history
  • Loading branch information
andreynovikov committed Mar 10, 2024
1 parent b65de3b commit 1ba6749
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 75 deletions.
29 changes: 6 additions & 23 deletions app/src/main/java/mobi/maptrek/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -924,10 +924,6 @@ protected void onStart() {
resultReceiver.setCallback(this);
mResultReceiver = new WeakReference<>(resultReceiver);

// Resume navigation
if (Configuration.getNavigationPoint() != null)
resumeNavigation();

if (Configuration.getConfirmExitEnabled())
getOnBackPressedDispatcher().addCallback(this, mBackPressedCallback);
mBackPressedCallback.setEnabled(mFragmentManager.getBackStackEntryCount() == 0);
Expand Down Expand Up @@ -998,11 +994,9 @@ public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
disableTracking();
});

SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if (sharedPreferences.getBoolean(NavigationService.PREF_NAVIGATION_BACKGROUND, false)) {
startService(new Intent(getApplicationContext(), NavigationService.class).setAction(BaseNavigationService.DISABLE_BACKGROUND_NAVIGATION));
enableNavigation();
}
// Resume navigation
if (Configuration.getNavigationPoint() != null)
resumeNavigation();

mMapEventLayer = new MapEventLayer(mMap, this);
mMap.layers().add(mMapEventLayer, MAP_EVENTS);
Expand Down Expand Up @@ -1075,19 +1069,8 @@ protected void onPause() {
if (trackViewModel.trackingState.getValue() != TRACKING_STATE.TRACKING)
stopService(new Intent(getApplicationContext(), LocationService.class));

if (mNavigationService != null) {
Intent intent = new Intent(getApplicationContext(), NavigationService.class);
if (mNavigationService.isNavigating()) {
if (Configuration.notificationsDenied()) {
stopNavigation();
stopService(intent);
} else {
startService(intent.setAction(BaseNavigationService.ENABLE_BACKGROUND_NAVIGATION));
}
} else {
stopService(intent);
}
}
if (mNavigationService != null && !mNavigationService.isNavigating())
stopService(new Intent(getApplicationContext(), NavigationService.class));
disableNavigation();
disableLocations();
}
Expand Down Expand Up @@ -2312,7 +2295,7 @@ private void updateLocationDrawable() {

private void updatePanels() {
logger.info("updatePanels()");
boolean isRouting = mNavigationService != null && mNavigationService.isNavigatingViaRoute();
boolean isRouting = mNavigationService != null && mNavigationService.isNavigating() && mNavigationService.isNavigatingViaRoute();

TransitionSet transitionSet = new TransitionSet();
Transition transition = new Slide(Gravity.START);
Expand Down
13 changes: 2 additions & 11 deletions app/src/main/java/mobi/maptrek/location/BaseNavigationService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Andrey Novikov
* Copyright 2024 Andrey Novikov
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
Expand Down Expand Up @@ -50,16 +50,6 @@ public abstract class BaseNavigationService extends Service
* Service command to stop navigation.
*/
public static final String STOP_NAVIGATION = "mobi.maptrek.location.stopNavigation";
/**
* Service command to start background mode. Service is switched to <em>Foreground</em>
* state to ensure it will not be killed by OS.
*/
public static final String ENABLE_BACKGROUND_NAVIGATION = "mobi.maptrek.location.enableBackgroundNavigation";
/**
* Service command to stop background mode. Service is switched back from <em>Foreground</em>
* state. Navigation is continued.
*/
public static final String DISABLE_BACKGROUND_NAVIGATION = "mobi.maptrek.location.disableBackgroundNavigation";

/**
* Map object id as returned by MapTrek. Used with NAVIGATE_TO_OBJECT action. Type: long
Expand Down Expand Up @@ -101,6 +91,7 @@ public abstract class BaseNavigationService extends Service
public static final int STATE_NEXT_ROUTE_POINT = 2;
public static final int STATE_REACHED = 3;
public static final int STATE_STOPPED = 4;
public static final int STATE_PAUSED = 5;

public static final int DIRECTION_FORWARD = 1;
public static final int DIRECTION_REVERSE = -1;
Expand Down
80 changes: 39 additions & 41 deletions app/src/main/java/mobi/maptrek/location/NavigationService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Andrey Novikov
* Copyright 2024 Andrey Novikov
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
Expand Down Expand Up @@ -69,7 +69,6 @@ public class NavigationService extends BaseNavigationService implements OnShared

private ILocationService mLocationService = null;
private Location mLastKnownLocation;
private boolean mForeground = false;

private boolean mUseTraverse = true;

Expand Down Expand Up @@ -118,7 +117,6 @@ public class NavigationService extends BaseNavigationService implements OnShared

private static final String PREF_NAVIGATION_PROXIMITY = "navigation_proximity";
private static final String PREF_NAVIGATION_TRAVERSE = "navigation_traverse";
public static final String PREF_NAVIGATION_BACKGROUND = "navigation_background";

@Override
public void onCreate() {
Expand Down Expand Up @@ -166,53 +164,40 @@ public int onStartCommand(Intent intent, int flags, int startId) {
setRoutePoint(start);
}
if (action.equals(RESUME_NAVIGATION)) {
if (navPoint != null) // we are already navigating
return START_NOT_STICKY;
navCurrentRoutePoint = Configuration.getNavigationRoutePoint();
navDirection = Configuration.getNavigationRouteDirection();
navPoint = Configuration.getNavigationPoint();
if (navPoint == null)
if (navPoint == null) { // we do not know what to resume
logger.error("No destination to resume");
return START_NOT_STICKY;
}
if (Configuration.getNavigationViaRoute()) {
loadRoute();
if (navRoute != null) {
resumeRoute();
} else {
logger.error("No route to resume");
stopNavigation();
stopNavigation(true);
}
} else {
resumePoint();
}
}
if (action.equals(STOP_NAVIGATION) || action.equals(PAUSE_NAVIGATION)) {
mForeground = false;
stopForeground(true);
startService(new Intent(getApplicationContext(), LocationService.class).setAction(BaseLocationService.DISABLE_BACKGROUND_LOCATIONS));
if (action.equals(STOP_NAVIGATION))
stopNavigation();
stopNavigation(false);
else
updateNavigationState(STATE_PAUSED);
Configuration.setNavigationViaRoute(navRoute != null);
Configuration.setNavigationRoutePoint(navCurrentRoutePoint);
Configuration.setNavigationRouteDirection(navDirection);
Configuration.setNavigationPoint(navPoint);
stopSelf();
}
if (action.equals(ENABLE_BACKGROUND_NAVIGATION) && navPoint != null) {
mForeground = true;
if (Build.VERSION.SDK_INT < 34)
startForeground(NOTIFICATION_ID, getNotification(true));
else
startForeground(NOTIFICATION_ID, getNotification(true), ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putBoolean(PREF_NAVIGATION_BACKGROUND, true);
editor.apply();
startService(new Intent(getApplicationContext(), LocationService.class).setAction(BaseLocationService.ENABLE_BACKGROUND_LOCATIONS));
}
if (action.equals(DISABLE_BACKGROUND_NAVIGATION)) {
mForeground = false;
navPoint = null;
stopForeground(true);
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putBoolean(PREF_NAVIGATION_BACKGROUND, false);
editor.apply();
startService(new Intent(getApplicationContext(), LocationService.class).setAction(BaseLocationService.DISABLE_BACKGROUND_LOCATIONS));
disconnect();
stopSelf();
}
updateNotification();

Expand All @@ -221,9 +206,8 @@ public int onStartCommand(Intent intent, int flags, int startId) {

@Override
public void onDestroy() {
disconnect();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
logger.debug("Service stopped");
logger.warn("Service stopped");
}

public class LocalBinder extends Binder implements INavigationService {
Expand Down Expand Up @@ -364,11 +348,14 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
private void connect() {
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
bindService(new Intent(this, LocationService.class), locationConnection, BIND_AUTO_CREATE);
startService(new Intent(getApplicationContext(), LocationService.class).setAction(BaseLocationService.ENABLE_BACKGROUND_LOCATIONS));
if (mLocationService == null)
bindService(new Intent(this, LocationService.class), locationConnection, BIND_AUTO_CREATE);
}

private void disconnect() {
EventBus.getDefault().unregister(this);
startService(new Intent(getApplicationContext(), LocationService.class).setAction(BaseLocationService.DISABLE_BACKGROUND_LOCATIONS));
if (mLocationService != null) {
mLocationService.unregisterLocationCallback(locationListener);
unbindService(locationConnection);
Expand Down Expand Up @@ -439,7 +426,7 @@ private Notification getNotification(boolean force) {
}

private void updateNotification() {
if (mForeground) {
if (navPoint != null) {
Notification notification = getNotification(false);
if (notification != null) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Expand All @@ -448,12 +435,13 @@ private void updateNotification() {
}
}

public void stopNavigation() {
public void stopNavigation(boolean disconnect) {
logger.debug("Stop navigation");
updateNavigationState(STATE_STOPPED);
stopForeground(true);
clearNavigation();
disconnect();
if (disconnect)
disconnect();
}

private void clearNavigation() {
Expand Down Expand Up @@ -484,24 +472,29 @@ private void clearNavigation() {

private void navigateTo(final MapObject point) {
if (navPoint != null)
stopNavigation();
stopNavigation(false);
navPoint = point;

resumePoint();
}

private void resumePoint() {
connect();

navProximity = navPoint.proximity > 0 ? navPoint.proximity : DEFAULT_POINT_PROXIMITY;
updateNavigationState(STATE_STARTED);
if (mLastKnownLocation != null)
calculateNavigationStatus();

if (Build.VERSION.SDK_INT < 34)
startForeground(NOTIFICATION_ID, getNotification(true));
else
//noinspection DataFlowIssue - can not be null because of force = true
startForeground(NOTIFICATION_ID, getNotification(true), ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
connect();
}

private void navigateTo(final Route route, final int direction) {
if (navPoint != null)
stopNavigation();
stopNavigation(false);
navRoute = route;
navDirection = direction;
navCurrentRoutePoint = navDirection == 1 ? 1 : navRoute.size() - 2;
Expand All @@ -511,8 +504,6 @@ private void navigateTo(final Route route, final int direction) {
}

private void resumeRoute() {
connect();

navPoint = new MapObject(navRoute.get(navCurrentRoutePoint));
prevPoint = new MapObject(navRoute.get(navCurrentRoutePoint - navDirection));
navProximity = DEFAULT_ROUTE_PROXIMITY;
Expand All @@ -522,6 +513,13 @@ private void resumeRoute() {
updateNavigationState(STATE_NEXT_ROUTE_POINT);
if (mLastKnownLocation != null)
calculateNavigationStatus();

if (Build.VERSION.SDK_INT < 34)
startForeground(NOTIFICATION_ID, getNotification(true));
else
//noinspection DataFlowIssue - can not be null because of force = true
startForeground(NOTIFICATION_ID, getNotification(true), ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
connect();
}

public void setRoutePoint(int point) {
Expand Down Expand Up @@ -723,7 +721,7 @@ else if (avgVMG[0] > 0)
nextRoutePoint();
} else {
updateNavigationState(STATE_REACHED);
stopNavigation();
stopNavigation(true);
}
return;
}
Expand Down

0 comments on commit 1ba6749

Please sign in to comment.