title: Understanding how Service, LocationListener and BroadcastReceiver work to get location in background
body: <p>I am new to <code>Android</code> and am working on building an app that tracks the users distance. It would only start tracking when the user taps a button, and stops when they tap again. There seems to be a large amount of confusion information and methods on how to do this, so I have I at least have a general idea of best practices.</p>
  
  <pre><code>public class BackgroundLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
  
      IBinder mBinder = new LocalBinder();
  
      private LocationClient mLocationClient;
      private LocationRequest mLocationRequest;
      private boolean mInProgress;
  
      //Milliseconds per second
    private static final int MILLISECONDS_PER_SECOND = 1000;
    // Update frequency in seconds
    private static final int UPDATE_INTERVAL_IN_SECONDS = 30;
    // Update frequency in milliseconds
    public static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
    // The fastest update frequency, in seconds
    private static final int FASTEST_INTERVAL_IN_SECONDS = 30;
    // A fast frequency ceiling in milliseconds
    public static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
    private static final int TWO_MINUTES = 1000 * 60 * 2;
  
    public Location previousBestLocation = null;
  
    private Boolean servicesAvailable = false;
  
    public class LocalBinder extends Binder {
      public BackgroundLocationService getServerInstance() {
          return BackgroundLocationService.this;
      }
    }
  
    @Override
      public void onCreate() {
        super.onCreate();
  
        mInProgress = false;
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
  
        // Check that Google Play Services are connected
        servicesAvailable = servicesConnected();
  
        // Create the client
        mLocationClient = new LocationClient(this, this, this);
  
    }//end
  
    private boolean servicesConnected() {
  
        // Check that Google Play services is available
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
  
        // If Google Play services is available
        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        } else {
            return false;
        }
  
    }//end
  
    public int onStartCommand (Intent intent, int flags, int startId) {
  
        super.onStartCommand(intent, flags, startId);
  
        if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
          return START_STICKY;
  
        setUpLocationClientIfNeeded();
        if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() &amp;&amp; !mInProgress) {
              mInProgress = true;
              mLocationClient.connect();
        }
  
        return START_STICKY;
    }//end
  
  
    private void setUpLocationClientIfNeeded() {
      if (mLocationClient == null) 
            mLocationClient = new LocationClient(this, this, this);
    }
  
  
    @Override
    public void onLocationChanged(Location location) {
  
        String msg = Double.toString(location.getLatitude()) + "," +Double.toString(location.getLongitude());
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
  
    }//end
  
    @Override
    public IBinder onBind(Intent intent) {
      return mBinder;
    }
  
    public String getTime() {
      SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      return mDateFormat.format(new Date());
    }
  
  
    @Override
    public void onDestroy(){
        // Turn off the request flag
        mInProgress = false;
        if(servicesAvailable &amp;&amp; mLocationClient != null) {
              mLocationClient.removeLocationUpdates(this);
              // Destroy the current location client
              mLocationClient = null;
        }
        // Display the connection status
        Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
        super.onDestroy();  
    }
  
    /*
     * Called by Location Services when the request to connect the
     * client finishes successfully. At this point, you can
     * request the current location or start periodic updates
     */
    @Override
    public void onConnected(Bundle bundle) {
  
        // Request location updates using static settings
        mLocationClient.requestLocationUpdates(mLocationRequest, this);
  
    }
  
    /*
     * Called by Location Services if the connection to the
     * location client drops because of an error.
     */
    @Override
    public void onDisconnected() {
        // Turn off the request flag
        mInProgress = false;
        // Destroy the current location client
        mLocationClient = null;
        // Display the connection status
        Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
  
    }
  
    /*
     * Called by Location Services if the attempt to
     * Location Services fails.
     */
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
      mInProgress = false;
  
        /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
  
        // If no resolution is available, display an error dialog
        } else {
  
        }
    }
  
  }
  </code></pre>
  
  <p><strong>So onto my questions:</strong></p>
  
  <ul>
  <li>From my main <code>Activity</code> how do I start my service? How do I stop it?</li>
  <li>How can my <code>Activity</code> class know when my <code>Service</code> receives <code>Location</code> updates so that I can update the UI?</li>
  <li>Do I even need a <code>BroadcastReceiver</code>?</li>
  <li>Does anything need to go into my <code>Manifest</code>?</li>
  </ul>