Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

How do I get the coordinates(Latitude and Longitude) of the current location?

I want to make a weather app which sets the weather according to the current location. So how do I get access to the coordinates of the user?

2 Answers

Dealing with GPS for Android can be a bit involved however using play services makes it simpler. Firstly, you'll need to determine the level of GPS (coarse or fine). For a weather app coarse should be sufficient. This will look at implementing GPS that updates while the app is active. However, the architecture we'll be using allows for easy modification (when you start and stop GPS services) to make introducing notifications to the app much easier. You'll need to include the following in the manifest of your app:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

The following is essentially pulled from the Google Dev Docs.

Firstly any Google Play Services class should implement ConnectionCallbacks and OnConnectionFailedListener and LocationListener. We should also create static three variables: a GoogleApiClient, a Location and a*LocationRequest*.

public class MainActivity extends Activity implements
    ConnectionCallbacks,  OnConnectionFailedListener, 
                         LocationListener {
      private static GoogleApiClient mGoogleApiClient;
      private static Location mCurrentLocation;
      private static LocationRequest mLocationRequest;
}

We need to create a Play Services client so we should spin this off into its own method so it can be easy to recreate when we need it. This is accomplished via a createClient method.

protected void createClient() {
   mGoogleApiClient = new GoogleApiClient.Builder(this)
           .addConnectionCallbacks(this)
           .addOnConnectionFailedListener(this)
           .addApi(LocationServices.API)
            .build();
}

We do the same for our LocationRequest with some additional work. We need to set the frequency with which we check our location. I would suggest an hour considering its a weather app. Assuming a freak weather incident we'll consider the fastest time the app should check the location on its own is every 15 minutes. This leaves us with 3600000 for hourly updates and 80000 for quarter-hour updates. Finally we need to establish the level of usage the app will be doing with GPS. The PRIORITY_LOW_POWER is probably best so as to not destroy the user's battery (its good for 10km range which gives ZIP code scale which is perfect for a weather app).

static final int HOURLY_UPDATE = 360000;
static final int QUARTER_HOUR_UPDATE = 80000;
protected void createLocationRequest() {
  mLocationRequest.setInterval(HOURLY_UPDATE);
  mLocationRequest.setFastestInterval(QUARTER_HOUR_UPDATE);
  mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
}

Now we can apply this methods in our onCreate function

protected void onCreate (Bundle savedInstanceState) {
   createBuilder(); 
   createLocationRequest();
}

We need a method to be responsible for starting the GPS services startGPSService and one for stopping the GPS services stopGPSService. We pass our request to the LocationServices class which is responsible for our interaction with the GPS. The method requestLocationUpdates begins the polling for location services where as removeLocationUpdates stops the specific updates we created earlier.

protected void startGPSService() {
     LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
 }

protected void stopGPSService() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

We then override the onConnected method which executes when the API Client connects to Play Services. We then setup our app to obtain GPS updates.

@Override
  public void onConnected(Bundle connectionHint) {
      startGPSService();
}

Now that we have the service implemented we should look to when we use battery. Assuming the user is opening the app to check the weather we can start and stop the services when the app is opened and closed. We'll be starting/stopping the GPS service is the onResume and onPause methods respectively:

@Override
public void onResume() {
    super.onResume();
    if (mGoogleApiClient.isConnected()) {
       startGPSService();
    }
}

@Override
public void onPause() {
   super.onPause();
   stopGPSService();
}

Finally we need to update our location information which is done via the overriden method onLocationChanged. Since the method is called indirectly we simply place the location we receive in mCurrentLocation.

@Override
public void onLocationChanged(Location location) {
   mCurrentLocation = location;
}

We can then access the latitude and longitude data from mCurrentLocation via the getLatitude and getLongitude methods:

public void updateWeather() {
   double lat = mCurrentLocation.getLatitude();
   double lgtd = mCurrentLocation.getLongitude();
   \\Do weather stuff
   \\UpdateUI
   \\Note: Copying the latitude and longitude to other 
   \\         variables is a moot point and you should just 
   \\         access the information from mCurrentLocation
   \\         directly.
} 

Finally throwing this all in a single class as a TL:DR. Also if you're looking for just to update using the last location every time the user opens the app check this out instead.

public class MainActivity extends Activity implements
    ConnectionCallbacks,  OnConnectionFailedListener,  LocationListener {
      private static GoogleApiClient mGoogleApiClient;
      private static Location mCurrentLocation;
      private static LocationRequest mLocationRequest;
      static int final HOURLY_UPDATE = 360000;
      static int final QUARTER_HOUR_UPDATE = 80000;

      protected void createClient() {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                         .addConnectionCallbacks(this)
                         .addOnConnectionFailedListener(this)
                         .addApi(LocationServices.API)
                         .build();
      }

      protected void createLocationRequest() {
           mLocationRequest.setInterval(HOURLY_UPDATE);
           mLocationRequest.setFastestInterval(QUARTER_HOUR_UPDATE);
           mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
     }

     protected void onCreate (Bundle savedInstanceState) {
          createBuilder(); 
          createLocationRequest();
     }

     protected void startGPSService() {
          LocationServices.FusedLocationApi.requestLocationUpdates(
                 mGoogleApiClient, mLocationRequest, this);
     }

     protected void stopGPSService() {
         LocationServices.FusedLocationApi.removeLocationUpdates(
               mGoogleApiClient, this);
     }

    @Override
     public void onConnected(Bundle connectionHint) {
          startGPSService();
     }

    @Override
     public void onResume() {
         super.onResume();
         if (mGoogleApiClient.isConnected()) {
              startGPSService();
        }
    }

   @Override
   public void onPause() {
        super.onPause();
        stopGPSService();
    }

   @Override 
   public void onLocationChanged(Location location) {
       mCurrentLocation = location;
    }

   public void updateWeather() {
       double lat = mCurrentLocation.getLatitude();
       double lgtd = mCurrentLocation.getLongitude();
       \\Do weather stuff
       \\UpdateUI
       \\Note: Copying the latitude and longitude to other 
       \\         variables is a moot point and you should just 
       \\         access the information from mCurrentLocation
       \\         directly.
    } 
}

Hope you find this useful. Cheers.

Thanks a lot!

@Manas Vijaywargiya

hie.... dd u manage to get the logic for challenge 4/4. can you explain to me

thank you