Move location request from broadcast receiver to service

This commit is contained in:
max-klaus 2020-11-12 10:22:48 +03:00
parent 7c81f72439
commit 21030cb58c
3 changed files with 42 additions and 58 deletions

View file

@ -1,5 +1,6 @@
package net.osmand.plus; package net.osmand.plus;
import android.annotation.SuppressLint;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
@ -33,16 +34,14 @@ public class NavigationService extends Service implements LocationListener {
// global id don't conflict with others // global id don't conflict with others
public static int USED_BY_NAVIGATION = 1; public static int USED_BY_NAVIGATION = 1;
public static int USED_BY_GPX = 2; public static int USED_BY_GPX = 2;
public static int USED_BY_LIVE = 4;
public final static String USAGE_INTENT = "SERVICE_USED_BY"; public final static String USAGE_INTENT = "SERVICE_USED_BY";
public final static String USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL"; public final static String USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL";
private NavigationServiceBinder binder = new NavigationServiceBinder(); private final NavigationServiceBinder binder = new NavigationServiceBinder();
private int serviceOffInterval; private int serviceOffInterval;
private String serviceOffProvider; private String serviceOffProvider;
private int serviceError; private int serviceErrorTimeout;
private long nextManualWakeup; private long nextManualWakeup;
private OsmandSettings settings; private OsmandSettings settings;
private Handler handler; private Handler handler;
@ -61,19 +60,11 @@ public class NavigationService extends Service implements LocationListener {
protected synchronized static PowerManager.WakeLock getLock(Context context) { protected synchronized static PowerManager.WakeLock getLock(Context context) {
if (lockStatic == null) { if (lockStatic == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmandServiceLock"); lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmAnd:NavigationServiceLock");
} }
return lockStatic; return lockStatic;
} }
protected Handler getHandler() {
return handler;
}
public int getServiceError() {
return serviceError;
}
public long getNextManualWakeup() { public long getNextManualWakeup() {
return nextManualWakeup; return nextManualWakeup;
} }
@ -90,10 +81,6 @@ public class NavigationService extends Service implements LocationListener {
return usedBy; return usedBy;
} }
public String getServiceOffProvider() {
return serviceOffProvider;
}
public boolean isUsed() { public boolean isUsed() {
return usedBy != 0; return usedBy != 0;
} }
@ -112,13 +99,9 @@ public class NavigationService extends Service implements LocationListener {
} else { } else {
// Issue #3604 // Issue #3604
final OsmandApplication app = (OsmandApplication) getApplication(); final OsmandApplication app = (OsmandApplication) getApplication();
if ((usedBy == 2) && (app.navigationServiceGpsInterval(app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get()) != 0) && (serviceOffInterval == 0)) { if ((usedBy == USED_BY_GPX) && (app.navigationServiceGpsInterval(app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get()) != 0) && (serviceOffInterval == 0)) {
serviceOffInterval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); serviceOffInterval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get();
// From onStartCommand: setupServiceErrorTimeout();
serviceError = serviceOffInterval / 5;
serviceError = Math.min(serviceError, 12 * 60 * 1000);
serviceError = Math.max(serviceError, 30 * 1000);
serviceError = Math.min(serviceError, serviceOffInterval);
app.setNavigationService(this); app.setNavigationService(this);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, OnNavigationServiceAlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT); pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, OnNavigationServiceAlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
@ -132,7 +115,6 @@ public class NavigationService extends Service implements LocationListener {
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent); alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent);
} }
} }
app.getNotificationHelper().updateTopNotification(); app.getNotificationHelper().updateTopNotification();
app.getNotificationHelper().refreshNotifications(); app.getNotificationHelper().refreshNotifications();
} }
@ -150,14 +132,7 @@ public class NavigationService extends Service implements LocationListener {
} }
// use only gps provider // use only gps provider
serviceOffProvider = LocationManager.GPS_PROVIDER; serviceOffProvider = LocationManager.GPS_PROVIDER;
serviceError = serviceOffInterval / 5; setupServiceErrorTimeout();
// 1. not more than 12 mins
serviceError = Math.min(serviceError, 12 * 60 * 1000);
// 2. not less than 30 seconds
serviceError = Math.max(serviceError, 30 * 1000);
// 3. not more than serviceOffInterval
serviceError = Math.min(serviceError, serviceOffInterval);
locationProvider = app.getLocationProvider(); locationProvider = app.getLocationProvider();
app.setNavigationService(this); app.setNavigationService(this);
@ -204,7 +179,6 @@ public class NavigationService extends Service implements LocationListener {
} }
} }
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -215,6 +189,15 @@ public class NavigationService extends Service implements LocationListener {
return serviceOffInterval == 0; return serviceOffInterval == 0;
} }
private void setupServiceErrorTimeout() {
serviceErrorTimeout = serviceOffInterval / 5;
// 1. not more than 12 mins
serviceErrorTimeout = Math.min(serviceErrorTimeout, 12 * 60 * 1000);
// 2. not less than 30 seconds
serviceErrorTimeout = Math.max(serviceErrorTimeout, 30 * 1000);
// 3. not more than serviceOffInterval
serviceErrorTimeout = Math.min(serviceErrorTimeout, serviceOffInterval);
}
@Override @Override
public void onDestroy() { public void onDestroy() {
@ -254,6 +237,29 @@ public class NavigationService extends Service implements LocationListener {
}, 500); }, 500);
} }
@SuppressLint("MissingPermission")
public void onWakeUp() {
// request location updates
final LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
locationManager.requestLocationUpdates(serviceOffProvider, 0, 0, this);
if (serviceOffInterval > serviceErrorTimeout) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
WakeLock lock = getLock(NavigationService.this);
if (lock.isHeld()) {
lock.release();
locationManager.removeUpdates(NavigationService.this);
}
}
}, serviceErrorTimeout);
}
} catch (RuntimeException e) {
// ignore
}
}
@Override @Override
public void onLocationChanged(Location l) { public void onLocationChanged(Location l) {
if (l != null && !settings.MAP_ACTIVITY_ENABLED.get()) { if (l != null && !settings.MAP_ACTIVITY_ENABLED.get()) {
@ -273,7 +279,6 @@ public class NavigationService extends Service implements LocationListener {
} }
locationProvider.setLocationFromService(location, isContinuous()); locationProvider.setLocationFromService(location, isContinuous());
} }
} }
@Override @Override

View file

@ -1,17 +1,18 @@
package net.osmand.plus; package net.osmand.plus;
import android.annotation.SuppressLint;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.location.LocationManager;
import android.os.Build; import android.os.Build;
import android.os.PowerManager.WakeLock; import android.os.PowerManager.WakeLock;
import android.os.SystemClock; import android.os.SystemClock;
public class OnNavigationServiceAlarmReceiver extends BroadcastReceiver { public class OnNavigationServiceAlarmReceiver extends BroadcastReceiver {
@SuppressLint("WakelockTimeout")
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
final WakeLock lock = NavigationService.getLock(context); final WakeLock lock = NavigationService.getLock(context);
@ -25,29 +26,9 @@ public class OnNavigationServiceAlarmReceiver extends BroadcastReceiver {
return; return;
} }
//
lock.acquire(); lock.acquire();
rescheduleAlarm(context, service); rescheduleAlarm(context, service);
service.onWakeUp();
// request location updates
final LocationManager locationManager = (LocationManager) service.getSystemService(Context.LOCATION_SERVICE);
try {
locationManager.requestLocationUpdates(service.getServiceOffProvider(), 0, 0, service);
if (service.getServiceOffInterval() > service.getServiceError()) {
service.getHandler().postDelayed(new Runnable() {
@Override
public void run() {
// if lock is not anymore held
if (lock.isHeld()) {
lock.release();
locationManager.removeUpdates(service);
}
}
}, service.getServiceError());
}
} catch (RuntimeException e) {
// ignore
}
} }
private void rescheduleAlarm(Context context, NavigationService service) { private void rescheduleAlarm(Context context, NavigationService service) {
@ -67,5 +48,4 @@ public class OnNavigationServiceAlarmReceiver extends BroadcastReceiver {
} }
} }
} }
} }

View file

@ -488,7 +488,6 @@ public class SavingTrackHelper extends SQLiteOpenHelper {
private void addTrackPoint(WptPt pt, boolean newSegment, long time) { private void addTrackPoint(WptPt pt, boolean newSegment, long time) {
List<TrkSegment> points = currentTrack.getModifiablePointsToDisplay(); List<TrkSegment> points = currentTrack.getModifiablePointsToDisplay();
Track track = currentTrack.getModifiableGpxFile().tracks.get(0); Track track = currentTrack.getModifiableGpxFile().tracks.get(0);
assert track.segments.size() == points.size();
if (points.size() == 0 || newSegment) { if (points.size() == 0 || newSegment) {
points.add(new TrkSegment()); points.add(new TrkSegment());
} }