Fix issue 405. Reimplement background service. Use alarm service to wake up phone
This commit is contained in:
parent
2991672d8f
commit
6c3ada7205
6 changed files with 119 additions and 55 deletions
|
@ -35,6 +35,7 @@
|
|||
<service android:process="net.osmand.plus" android:label="@string/process_navigation_service" android:name=".NavigationService">
|
||||
<intent-filter><action android:name="net.osmand.plus.NavigationService"></action></intent-filter>
|
||||
</service>
|
||||
<receiver android:name=".OnNavigationServiceAlarmReceiver"/>
|
||||
</application>
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import net.osmand.Version;
|
|||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import net.osmand.plus.activities.RoutingHelper;
|
||||
import net.osmand.plus.activities.SavingTrackHelper;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
|
@ -21,6 +22,9 @@ import android.os.Binder;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class NavigationService extends Service implements LocationListener {
|
||||
|
@ -30,62 +34,57 @@ 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$
|
||||
|
||||
private NavigationServiceBinder binder = new NavigationServiceBinder();
|
||||
|
||||
|
||||
private int serviceOffInterval;
|
||||
private String serviceOffProvider;
|
||||
private SavingTrackHelper savingTrackHelper;
|
||||
private Handler handler;
|
||||
private int serviceError;
|
||||
|
||||
private SavingTrackHelper savingTrackHelper;
|
||||
private RoutingHelper routingHelper;
|
||||
private Notification notification;
|
||||
private SharedPreferences settings;
|
||||
private boolean serviceActive = true;
|
||||
private boolean registered = false;
|
||||
|
||||
private Handler handler;
|
||||
|
||||
private static WakeLock lockStatic;
|
||||
private PendingIntent pendingIntent;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
protected synchronized static PowerManager.WakeLock getLock(Context context) {
|
||||
if (lockStatic == null) {
|
||||
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmandServiceLock");
|
||||
}
|
||||
return lockStatic;
|
||||
}
|
||||
|
||||
protected Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public int getServiceError() {
|
||||
return serviceError;
|
||||
}
|
||||
|
||||
private void delayedAction(final boolean register, long delay){
|
||||
handler.postDelayed(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!serviceActive) {
|
||||
return;
|
||||
}
|
||||
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
if (register) {
|
||||
registered = true;
|
||||
locationManager.requestLocationUpdates(serviceOffProvider, 1000, 0, NavigationService.this);
|
||||
// Wait serviceError and
|
||||
if (!isContinuous() || serviceOffInterval > serviceError) {
|
||||
delayedAction(false, serviceError);
|
||||
}
|
||||
} else {
|
||||
// That is needed to not remove twice
|
||||
// RemovingUpdates : after serviceError and after successful found position
|
||||
if(registered){
|
||||
registered = false;
|
||||
locationManager.removeUpdates(NavigationService.this);
|
||||
delayedAction(true, serviceOffInterval);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}, delay);
|
||||
|
||||
public int getServiceOffInterval() {
|
||||
return serviceOffInterval;
|
||||
}
|
||||
|
||||
public String getServiceOffProvider() {
|
||||
return serviceOffProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// initializing variables
|
||||
setForeground(true);
|
||||
serviceActive = true;
|
||||
handler = new Handler();
|
||||
settings = OsmandSettings.getSharedPreferences(this);
|
||||
serviceOffInterval = OsmandSettings.getServiceOffInterval(settings);
|
||||
|
@ -94,8 +93,21 @@ public class NavigationService extends Service implements LocationListener {
|
|||
savingTrackHelper = new SavingTrackHelper(this);
|
||||
|
||||
routingHelper = ((OsmandApplication)getApplication()).getRoutingHelper();
|
||||
OsmandSettings.setServiceOffEnabled(this, true);
|
||||
((OsmandApplication)getApplication()).setNavigationService(this);
|
||||
|
||||
|
||||
// requesting
|
||||
if(isContinuous()){
|
||||
// request location updates
|
||||
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
locationManager.requestLocationUpdates(serviceOffProvider, 1000, 0, NavigationService.this);
|
||||
} else {
|
||||
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, OnNavigationServiceAlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent);
|
||||
}
|
||||
|
||||
// registering icon at top level
|
||||
registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
@ -103,11 +115,8 @@ public class NavigationService extends Service implements LocationListener {
|
|||
}
|
||||
|
||||
}, new IntentFilter(OSMAND_STOP_SERVICE_ACTION));
|
||||
|
||||
// register listener
|
||||
delayedAction(true, 500);
|
||||
Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION);
|
||||
notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$
|
||||
Notification notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$
|
||||
System.currentTimeMillis());
|
||||
notification.flags = Notification.FLAG_NO_CLEAR;
|
||||
notification.setLatestEventInfo(this, Version.APP_NAME,
|
||||
|
@ -125,10 +134,22 @@ public class NavigationService extends Service implements LocationListener {
|
|||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
((OsmandApplication)getApplication()).setNavigationService(null);
|
||||
|
||||
// remove updates
|
||||
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
locationManager.removeUpdates(this);
|
||||
OsmandSettings.setServiceOffEnabled(this, false);
|
||||
serviceActive = false;
|
||||
|
||||
if (!isContinuous()) {
|
||||
WakeLock lock = getLock(this);
|
||||
if (lock.isHeld()) {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
// remove alarm
|
||||
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
alarmManager.cancel(pendingIntent);
|
||||
// remove notification
|
||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
mNotificationManager.cancel(NOTIFICATION_SERVICE_ID);
|
||||
|
||||
|
@ -141,7 +162,9 @@ public class NavigationService extends Service implements LocationListener {
|
|||
if(location != null && !OsmandSettings.getMapActivityEnabled(settings)){
|
||||
if(!isContinuous()){
|
||||
// unregister listener and wait next time
|
||||
delayedAction(false, 500);
|
||||
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
locationManager.removeUpdates(this);
|
||||
getLock(this).release();
|
||||
}
|
||||
savingTrackHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(),
|
||||
location.getSpeed(), location.getTime(), settings);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import net.osmand.plus.activities.OsmandApplication;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.LocationManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
|
||||
public class OnNavigationServiceAlarmReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final WakeLock lock = NavigationService.getLock(context);
|
||||
final NavigationService service = ((OsmandApplication) context.getApplicationContext()).getNavigationService();
|
||||
// do not do nothing
|
||||
if (lock.isHeld() || service == null) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
lock.acquire();
|
||||
// request location updates
|
||||
final LocationManager locationManager = (LocationManager) service.getSystemService(Context.LOCATION_SERVICE);
|
||||
locationManager.requestLocationUpdates(service.getServiceOffProvider(), 1000, 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -779,15 +779,7 @@ public class OsmandSettings {
|
|||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
public static final String SERVICE_OFF_ENABLED = "service_off_enabled"; //$NON-NLS-1$
|
||||
public static final boolean SERVICE_OFF_ENABLED_DEF = false;
|
||||
public static boolean getServiceOffEnabled(SharedPreferences prefs) {
|
||||
return prefs.getBoolean(SERVICE_OFF_ENABLED, SERVICE_OFF_ENABLED_DEF);
|
||||
}
|
||||
|
||||
public static boolean setServiceOffEnabled(Context ctx, boolean en) {
|
||||
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||
return prefs.edit().putBoolean(SERVICE_OFF_ENABLED, en).commit();
|
||||
}
|
||||
|
||||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
import net.osmand.Algoritms;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.plus.FavouritesDbHelper;
|
||||
import net.osmand.plus.NavigationService;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.PoiFiltersHelper;
|
||||
import net.osmand.plus.ProgressDialogImplementation;
|
||||
|
@ -45,6 +46,7 @@ public class OsmandApplication extends Application {
|
|||
private ProgressDialog progressDlg;
|
||||
private Handler uiHandler;
|
||||
private DayNightHelper daynightHelper;
|
||||
private NavigationService navigationService;
|
||||
|
||||
|
||||
public void onCreate(){
|
||||
|
@ -158,6 +160,14 @@ public class OsmandApplication extends Application {
|
|||
}
|
||||
return player.init(OsmandSettings.getVoiceProvider(OsmandSettings.getPrefs(this)));
|
||||
}
|
||||
|
||||
public NavigationService getNavigationService() {
|
||||
return navigationService;
|
||||
}
|
||||
|
||||
public void setNavigationService(NavigationService navigationService) {
|
||||
this.navigationService = navigationService;
|
||||
}
|
||||
|
||||
public void startApplication() {
|
||||
startDialog = new ProgressDialogImplementation(this, null, false);
|
||||
|
|
|
@ -265,7 +265,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
|||
new String[]{LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER}, //
|
||||
OsmandSettings.getServiceOffProvider(prefs));
|
||||
|
||||
routeServiceEnabled.setChecked(OsmandSettings.getServiceOffEnabled(prefs));
|
||||
routeServiceEnabled.setChecked(getMyApplication().getNavigationService() != null);
|
||||
|
||||
fill(mapScreenOrientation, //
|
||||
new String[] {
|
||||
|
@ -484,11 +484,11 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
|||
if ((Boolean) newValue) {
|
||||
ComponentName name = startService(serviceIntent);
|
||||
if (name == null) {
|
||||
routeServiceEnabled.setChecked(OsmandSettings.getServiceOffEnabled(prefs));
|
||||
routeServiceEnabled.setChecked(getMyApplication().getNavigationService() != null);
|
||||
}
|
||||
} else {
|
||||
if(!stopService(serviceIntent)){
|
||||
routeServiceEnabled.setChecked(OsmandSettings.getServiceOffEnabled(prefs));
|
||||
routeServiceEnabled.setChecked(getMyApplication().getNavigationService() != null);
|
||||
}
|
||||
}
|
||||
} else if (preference == routerPreference) {
|
||||
|
|
Loading…
Reference in a new issue