diff --git a/app/src/main/java/mobi/maptrek/MainActivity.java b/app/src/main/java/mobi/maptrek/MainActivity.java index effd6685..1c25ee41 100644 --- a/app/src/main/java/mobi/maptrek/MainActivity.java +++ b/app/src/main/java/mobi/maptrek/MainActivity.java @@ -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); @@ -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); @@ -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(); } @@ -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); diff --git a/app/src/main/java/mobi/maptrek/location/BaseNavigationService.java b/app/src/main/java/mobi/maptrek/location/BaseNavigationService.java index 5dee0db3..cd27ade3 100644 --- a/app/src/main/java/mobi/maptrek/location/BaseNavigationService.java +++ b/app/src/main/java/mobi/maptrek/location/BaseNavigationService.java @@ -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 @@ -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 Foreground - * 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 Foreground - * 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 @@ -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; diff --git a/app/src/main/java/mobi/maptrek/location/NavigationService.java b/app/src/main/java/mobi/maptrek/location/NavigationService.java index f3ee69eb..dc02f745 100644 --- a/app/src/main/java/mobi/maptrek/location/NavigationService.java +++ b/app/src/main/java/mobi/maptrek/location/NavigationService.java @@ -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 @@ -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; @@ -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() { @@ -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(); @@ -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 { @@ -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); @@ -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); @@ -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() { @@ -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; @@ -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; @@ -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) { @@ -723,7 +721,7 @@ else if (avgVMG[0] > 0) nextRoutePoint(); } else { updateNavigationState(STATE_REACHED); - stopNavigation(); + stopNavigation(true); } return; }