package com.maciekjanusz.compassproject.navigation; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.location.Location; import android.os.IBinder; import android.support.v7.app.NotificationCompat; import android.util.Log; import com.google.android.gms.location.LocationListener; import com.google.android.gms.maps.model.LatLng; import com.maciekjanusz.compassproject.ui.CompassActivity; import com.maciekjanusz.compassproject.R; import de.greenrobot.event.EventBus; import static com.maciekjanusz.compassproject.util.CompassMath.calculateBearing; import static com.maciekjanusz.compassproject.util.CompassMath.calculateDistance; public class NavigationService extends Service implements LocationListener { private static final String TAG = "NavService"; public static final String EXTRA_DESTINATION = "extra_destination"; private LocationRetriever locationRetriever; private double destLat, destLon; private volatile ServiceState currentState = ServiceState.NAVIGATION_STOPPED; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); locationRetriever = new LocationRetriever(this); EventBus.getDefault().register(this); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand()"); if(intent != null && intent.hasExtra(EXTRA_DESTINATION)) { LatLng latLng = intent.getParcelableExtra(EXTRA_DESTINATION); destLat = latLng.latitude; destLon = latLng.longitude; } else { stopSelf(); } locationRetriever.registerLocationListener(this); locationRetriever.startRetrievingLocation(); startForeground(startId, createServiceRunningNotification()); currentState = ServiceState.NAVIGATION_RUNNING; EventBus.getDefault().post(currentState); return START_STICKY; } @Override public void onDestroy() { Log.i(TAG, "onDestroy()"); locationRetriever.stopRetrievingLocation(); locationRetriever.unregisterLocationListener(this); currentState = ServiceState.NAVIGATION_STOPPED; EventBus.getDefault().post(currentState); EventBus.getDefault().unregister(this); super.onDestroy(); } @Override public void onLocationChanged(Location location) { // prepare and post navigation bundle to anyone who cares double fromLon = location.getLongitude(); double fromLat = location.getLatitude(); float bearing = (float) calculateBearing(fromLat, fromLon, destLat, destLon); float distance = (float) calculateDistance(fromLat, fromLon, destLat, destLon); EventBus.getDefault().post(new NavigationBundle(location, bearing, distance, new LatLng(destLat, destLon))); } private Notification createServiceRunningNotification() { NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext()); PendingIntent pendingIntent = PendingIntent .getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), CompassActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); builder.setSmallIcon(R.drawable.ic_navigation_white_48dp) .setContentIntent(pendingIntent) .setContentTitle(String.format(getString(R.string.navigation_service_content_title_format), destLat, destLon)) .setContentText(getString(R.string.navigation_service_content_text)); return builder.build(); } @SuppressWarnings("unused") public void onEvent(ServiceMessage serviceMessage) { switch (serviceMessage) { case REQUEST_NAVIGATION_SERVICE_STATE: // post current state EventBus.getDefault().post(currentState); // if current location is known, go through onLocationChanged // and eventually post the navigationBundle Location currentLocation = locationRetriever.getCurrentLocation(); if(currentLocation != null) { onLocationChanged(currentLocation); } break; } } }