title: (Android) Getting a GPS Location via Service / App Stopped Working
body: <p>I'm writing an app in which the main activity should bind to a service when clicking on a button. The service should get the GPS location. I keep getting the message "Unfortunately, the app has stopped" whenever debugging... </p>
  
  <p>Here's AndroidManifest.xml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="com.MyApp"
            android:versionCode="1"
            android:versionName="1.0"&gt;
      &lt;uses-sdk
              android:minSdkVersion="8"
              android:targetSdkVersion="23"/&gt;
      &lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
      &lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /&gt;
      &lt;application
              android:allowBackup="true"
              android:label="@string/app_name"
              android:icon="@drawable/ic_launcher"&gt;
          &lt;meta-data android:name="com.google.android.gms.version"
                     android:value="@integer/google_play_services_version" /&gt;
          &lt;activity
                  android:name=".Main"
                  android:label="@string/app_name"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN"/&gt;
                  &lt;category android:name="android.intent.category.LAUNCHER"/&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
          &lt;service
                  android:name=".GPSLocation" android:label="GPS Location"
                  android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
                  android:enabled="true"&gt;
          &lt;/service&gt;
      &lt;/application&gt;
  &lt;/manifest&gt;
  </code></pre>
  
  <p>Here's Main.java: </p>
  
  <pre><code>public class Main extends Activity {
  
      // UI elements
      private static Context context;
      private TextView lblLocation;
      private Button btnStartService;
      private Button btnShowLocation;
      private Button btnGetClosestBusStop;
  
      GPSLocation mService;
      Location location;
      boolean mBound = false;
  
      private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
  
          lblLocation = (TextView) findViewById(R.id.lblLocation);
          btnStartService = (Button) findViewById(R.id.btnStartService);
          btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
          btnGetClosestBusStop = (Button) findViewById(R.id.btnGetClosestBusStop);
      }
  
      @Override
      protected void onStart() {
          super.onStart();
          final Intent intent = new Intent(Main.this, GPSLocation.class);
          btnStartService.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  // First we need to check availability of play services
                  if (checkPlayServices()) {
                      //getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
                      bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
                  }
              }
          });
  
          btnShowLocation.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  if (mBound) {
                      displayLocation();
                  }
              }
          });
      }
  
      @Override
      protected void onResume() {
          super.onResume();
          checkPlayServices();
      }
  
      @Override
      protected void onStop() {
          super.onStop();
      }
  
      @Override
      protected void onPause() {
          super.onPause();
      }
  
      @Override
      protected void onDestroy() {
          super.onDestroy();
      }
  
      /**
       * Method to verify google play services on the device
       * */
      private boolean checkPlayServices() {
          int resultCode = GooglePlayServicesUtil
                  .isGooglePlayServicesAvailable(this);
          if (resultCode != ConnectionResult.SUCCESS) {
              if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                  GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                          PLAY_SERVICES_RESOLUTION_REQUEST).show();
              } else {
                  Toast.makeText(getApplicationContext(),
                          "This device is not supported.", Toast.LENGTH_LONG)
                          .show();
                  finish();
              }
              return false;
          }
          return true;
      }
  
      /**
       * Method to display the location on UI
       * */
      private void displayLocation() {
          location = mService.mLastLocation;
          if (location != null) {
              double latitude = location.getLatitude();
              double longitude = location.getLongitude();
              lblLocation.setText(latitude + ", " + longitude);
          } else {
              lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
          }
      }
  
      private ServiceConnection myConnection = new ServiceConnection() {
          @Override
          public void onServiceConnected(ComponentName className, IBinder binder) {
              GPSLocation.MyBinder bin = (GPSLocation.MyBinder) binder;
              mService = bin.getService();
              location = bin.getLocation();
              mBound = true;
              Log.d("ServiceConnection", "connected");
          }
  
          @Override
          public void onServiceDisconnected(ComponentName className) {
              Log.d("ServiceConnection","disconnected");
              mBound = false;
          }
      };
  }
  </code></pre>
  
  <p>Here's GPSLocation.java: </p>
  
  <pre><code>public class GPSLocation extends Service implements GoogleApiClient.ConnectionCallbacks,
          GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
  
      private static final String TAG = GPSLocation.class.getSimpleName();
      private final IBinder mBinder = new MyBinder();
      private Messenger outMessenger;
      public Location mLastLocation;
  
      // Google client to interact with Google API
      private GoogleApiClient mGoogleApiClient;
  
      // boolean flag to toggle periodic location updates
      private boolean mRequestingLocationUpdates = false;
  
      private LocationRequest mLocationRequest;
  
      // Location updates intervals in sec
      private static int UPDATE_INTERVAL = 10000; // 10 sec
      private static int FATEST_INTERVAL = 5000; // 5 sec
      private static int DISPLACEMENT = 10; // 10 meters
  
      public class MyBinder extends Binder {
          GPSLocation getService() {
              return GPSLocation.this;
          }
          Location getLocation() {
              return GPSLocation.this.mLastLocation;
          }
      }
  
      @Override
      public IBinder onBind(Intent intent) {
          return mBinder;
      }
  
      @Override
      public void onCreate() {
          // Building the Google API client
          buildGoogleApiClient();
  
          createLocationRequest();
  
          togglePeriodicLocationUpdates();
      }
  
      /**
       * Creating Google API client object
       * */
      protected synchronized void buildGoogleApiClient() {
          mGoogleApiClient = new GoogleApiClient.Builder(this)
                  .addConnectionCallbacks(this)
                  .addOnConnectionFailedListener(this)
                  .addApi(LocationServices.API).build();
      }
  
      /**
       * Creating location request object
       * */
      protected void createLocationRequest() {
          mLocationRequest = new LocationRequest();
          mLocationRequest.setInterval(UPDATE_INTERVAL);
          mLocationRequest.setFastestInterval(FATEST_INTERVAL);
          mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
          mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
      }
  
      /**
       * Method to toggle periodic location updates
       * */
      public void togglePeriodicLocationUpdates() {
          if (!mRequestingLocationUpdates) {
              mRequestingLocationUpdates = true;
  
              // Starting the location updates
              startLocationUpdates();
  
              Log.d(TAG, "Periodic location updates started!");
  
              mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
  
          }
      }
  
      /**
       * Starting the location updates
       * */
      protected void startLocationUpdates() {
  
          LocationServices.FusedLocationApi.requestLocationUpdates(
                  mGoogleApiClient, mLocationRequest, this);
      }
  
      /**
       * Stopping location updates
       */
      protected void stopLocationUpdates() {
          LocationServices.FusedLocationApi.removeLocationUpdates(
                  mGoogleApiClient, this);
      }
  
      /**
       * Google API callback methods
       */
      @Override
      public void onConnectionFailed(ConnectionResult result) {
          Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
      }
  
      @Override
      public void onConnected(Bundle arg0) {
          if (mRequestingLocationUpdates) {
              startLocationUpdates();
          }
      }
  
      @Override
      public void onConnectionSuspended(int arg0) {
          mGoogleApiClient.connect();
      }
  
      @Override
      public void onLocationChanged(Location location) {
          // Assign the new location
          mLastLocation = location;
      }
  }
  </code></pre>
  
  <p>And here's the logcat message: </p>
  
  <pre><code>11-17 03:44:58.157  29408-29408/com.WaitOrWalk E/AndroidRuntime﹕ FATAL EXCEPTION: main
      Process: com.MyApp, PID: 29408
      java.lang.RuntimeException: Unable to create service com.MyApp.GPSLocation: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
              at android.app.ActivityThread.handleCreateService(ActivityThread.java:2912)
              at android.app.ActivityThread.access$1800(ActivityThread.java:144)
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455)
              at android.os.Handler.dispatchMessage(Handler.java:102)
              at android.os.Looper.loop(Looper.java:155)
              at android.app.ActivityThread.main(ActivityThread.java:5696)
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
       Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
              at com.google.android.gms.internal.zzlh.zzb(Unknown Source)
              at com.google.android.gms.internal.zzli.zzb(Unknown Source)
              at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
              at com.MyApp.GPSLocation.startLocationUpdates(GPSLocation.java:107)
              at com.MyApp.GPSLocation.togglePeriodicLocationUpdates(GPSLocation.java:87)
              at com.MyApp.GPSLocation.onCreate(GPSLocation.java:55)
              at android.app.ActivityThread.handleCreateService(ActivityThread.java:2894)
              at android.app.ActivityThread.access$1800(ActivityThread.java:144)
              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1455)
              at android.os.Handler.dispatchMessage(Handler.java:102)
              at android.os.Looper.loop(Looper.java:155)
              at android.app.ActivityThread.main(ActivityThread.java:5696)
              at java.lang.reflect.Method.invoke(Native Method)
              at java.lang.reflect.Method.invoke(Method.java:372)
              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
  </code></pre>
  
  <p>I'd really appreciate some help, been stuck on this for a while... The app crashes on <code>bindService(intent, myConnection, Context.BIND_AUTO_CREATE);</code></p>