Guide to getting Location in Android(Address) — Part 2

pic courtesy: https://www.geospatialworld.net/

In the last part of this tutorial, we have seen how to get the current location(latitude and longitude) with google’s fusedlocationapi. Please check it out if you haven’t already because this is a continuation of that tutorial.

So from the last part, we have got a location object and we need to get the address of the location. The process of converting coordinates to address is called reverse geocoding, and we can use this to look up the address from our coordinates.

We will be using getFromLocation() of the Geocoder class to get the location. This method is synchronous, so we should not use the main thread to invoke this method. We can use IntentService to call the method, which will run long running tasks like this in the background without affecting the UI’s responsiveness.

To do this, create a new class called FetchAddressIntentService that extends IntentService

public class FetchAddressIntentService extends IntentService {

This service will handle our address lookup task on a worker thread and will stop itself when it runs out of work.

Now we need to add an entry to apps manifest inside the application section to tell Android that the app uses an intentservice as shown below:

<service

We will need to define some unique constant keys to be used by our service and receiver(will be mentioned later). So let’s create a public final class of constants that can be accessed from different classes.

public final class Constants {

We need to create a Geocoder object inside the onHandleIntent method to convert the Location to address. We also need to pass a Locale object to ensure the resulting address is localized to users geographic location. The getFromLocation() will return an array of Addresses that are known to describe the area immediately surrounding the given latitude and longitude. The location object and resultreceiver(discussed later) will be passed to the service from where the intentservice is invoked, here it will be MainActivity.

private ResultReceiver mReceiver;

Now we need to deliver our address from the intent service to the activity so that we can update the UI. We can use ResultReceiver for receiving the address from the IntentService. The ResultReceiver class allows you to send a numeric result code as well as a message containing the result data. The numeric code is useful for reporting the success or failure of the geocoding request. We need to define a method that will transfer the address to the Activity:

private void deliverResultToReceiver(int resultCode, String message) {

mReceiver is the object of ResultReceiver send from the MainActivity which is received along with the location object. Now from the onHandleIntent method, we must call this deliverResultToReceiver() so as to send the address to the MainActivity

@Override

This is all that we have to do to the IntentService. Now we need to start this intentservice from the MainActivity. We can use the following method to start the IntentReceiver.

private void startIntentService() {

Where mLastLocation is the object of Location and mResultReceiver is an object of the class ResultReceiver class that we are going to create.

For setting up a ResultReceiver we are going to make an inner class inside the MainActivity which will receive the result that we send form the FetchAddressIntentService. Then we will create a method inside the MainActivity to update our UI.

public class MainActivity extends AppCompatActivity {

In the overridden method onReceiveResult we will get the result that we send from the intentservice with mReceiver.send(..)

Now we can make displayAddressOutput() in the MainActivity to update our UI. In android we can only update the UI from the main thread so we have to use runOnUiThread as shown below:

private void displayAddressOutput(final String addressText){

That’s it. now we can see the address that we receive from the intent receiver in the textview.

You can find the code for the app here. Happy coding :)

Software Engineer