package net.osmand.plus; 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; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; 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 { public static class NavigationServiceBinder extends Binder { } 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 int serviceError; private SavingTrackHelper savingTrackHelper; private RoutingHelper routingHelper; private SharedPreferences settings; 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; } public int getServiceOffInterval() { return serviceOffInterval; } public String getServiceOffProvider() { return serviceOffProvider; } @Override public void onCreate() { super.onCreate(); // initializing variables setForeground(true); handler = new Handler(); settings = OsmandSettings.getSharedPreferences(this); serviceOffInterval = OsmandSettings.getServiceOffInterval(settings); serviceOffProvider = OsmandSettings.getServiceOffProvider(settings); serviceError = OsmandSettings.getServiceOffWaitInterval(settings); savingTrackHelper = new SavingTrackHelper(this); routingHelper = ((OsmandApplication)getApplication()).getRoutingHelper(); ((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) { NavigationService.this.stopSelf(); } }, new IntentFilter(OSMAND_STOP_SERVICE_ACTION)); Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION); Notification notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$ System.currentTimeMillis()); notification.flags = Notification.FLAG_NO_CLEAR; notification.setLatestEventInfo(this, Version.APP_NAME, 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); } private boolean isContinuous(){ return serviceOffInterval == 0; } @Override public void onDestroy() { super.onDestroy(); ((OsmandApplication)getApplication()).setNavigationService(null); // remove updates LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); locationManager.removeUpdates(this); 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); } @Override public void onLocationChanged(Location location) { if(location != null && !OsmandSettings.getMapActivityEnabled(settings)){ if(!isContinuous()){ // unregister listener and wait next time 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); if(routingHelper.isFollowingMode()){ routingHelper.setCurrentLocation(location); } } } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, getString(R.string.off_router_service_no_gps_available), Toast.LENGTH_LONG).show(); } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } }