Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Google Directions API: Tracing routes in Android

Discover in this article how simple it is to make use of geolocation on your mobile applications using the Google Directions API in Android development.

This article aims to present the integration of the Google API on devices running the Android operating system. The execution of such integration will be demonstrated through a simple example where a navigation route will be implemented through a point of origin and destination entered by the user using the Google API for geolocation, Google Directions API.

The term refers geolocation to identify the geographic location in the real world of an object, like a radar, mobile phone or computer terminal connected to the Internet.

In computing, a geolocation software is used to infer the geographic location of Internet connected device, using as one of the possible approaches identifying IP number of the device, to finally get to its location.

Services based on geolocation (SLBL'S) are generally divided into two main categories: 'push' services and 'pull' services. Push services imply that a user receives information (depending on your location) without having to request it actively. A practical example would be sending a notification of offers from a shop from which the user is approaching.

In the case of pull services, information is only sent to the user if it requests explicitly. An example would be in case the user wants to know where the nearest restaurant.

The geolocation opens a wide niche of applications to be explored, such as:

  • Information Services: The services in this category provide instructions on how to reach a desired destination, indicate where to find a particular service or person nearby, or locate a lost user on a map;
  • Emergency Services: In emergencies, the time factor is usually crucial to prevent more serious consequences. The use of location technologies enables faster response time, from the moment that occurs the fact in question until the time it reaches the request. The clearest applications of this category would be in the medical field and in the security area. Old people or people with some kind of disease could have their vital signs monitored by mobile devices, and these automatically emit a warning signal if an abnormality is detected. For security applications, this signal could be triggered by the user, or in consequence of a suspicious event. The transmitted signal would indicate the user's location and rescue teams would be displaced to the location;
  • Tracing Services: A clear example of application of this category is tracking vehicle fleets carrying goods. You can monitor the entire route of each vehicle and identify suspicious behavior in the case of unplanned itinerary changes. This application is particularly useful for insurers because it increases the chances of finding the vehicle in the event of a claim;
  • Information Dissemination Services: A practical example would be the dissemination of advertisements. Advertisers could send temporary promotion messages to potential customers who are in the vicinity of its establishment, and a new custom type of B2C (Business to Consumer) would be established in a dynamic and localized form, vastly increasing the efficiency of the ads and the sales potential. A practical example would be a restaurant offering meal deals to people walking through the neighborhood during the lunch hour.

Getting the location of an object

There are basically two ways to obtain the geographic location of an object: GPS and the triangulation of antennas.

GPS

In tracking using GPS, the embedded device determines its own position after connecting to at least four satellites in a constellation of US satellites. With the data received, the equipment crawler can calculate its position, and thus the position of the vehicle in which it is embedded.

After this, it must send this data to a central, which will show graphically the location of the vehicle. This may be sent either via phone (usually via GPRS) or satellite. To send satellite communication units with the earth, the satellite sends the position of the vehicle to a communication station which in turn sends the intermediate stations, servers, or even directly to computers, enabling the location of the vehicle.

It is also possible to reverse communication, both the tracker via GPRS Mobile as the X in the satellite. In the case of satellite tracking, for example, sending commands is possible like: a lock, where the command starts in a computer to follow the satellite earth station then would pass through the orbiting satellite to the vehicle, reaching it.

Triangulation of Antennas

In the tracking system of triangulating of antennas, a radio network is built exclusively for this purpose. The antennas receive the radio signal from a device installed in the vehicle and, based on this signal and the known position of the antennas, we calculate the vehicle position. There is no need in this case of a second means for sending the position information as in the case of GPS. Everything is done via the own radio network set up for the service.

Several companies working with vehicle fleets have also joined the tracker device that besides used to ensure greater security, can be used as a source of more specific information. As with the tracking of vehicles, it is possible to calculate the time of a given delivery.

Example of geolocation applications

Find Friend

Developed by AT&T and commercially available in some cities in the US, the Find Friend, as the name suggests, is an application to approach people. It allows a user to locate people (previously registered) and arrange to meet with them. The application can also suggest places of meetings as restaurants, and directions - with the help of maps - to reach the agreed place.

Waze

Waze is a GPS geographic based in navigation application programmed for smartphones that provides real-time information and user information and route details, downloading information depending on the portable device location on the network. It was developed by Israeli startup Waze Mobile, which was acquired by Google in 2013. People can report accidents, congestion, speed, 'blitzes' police, and can upgrade roads, landmarks, house numbers, etc. The Waze also identifies the cheapest gas stations near the user through your route. In January 2012, the application had been downloaded 12 million times worldwide. In July 2012 the Waze announced that it had reached the 20 million users, half of them recruited in the last 6 months. According to Yahoo!, there were about 50 million Waze users in June 2013.

Overview of Google Directions API

In June 2005, Google launched the Google Maps API, a platform that enables developers to integrate Google Maps into their applications. Using this API, it is possible to embed the Google Maps web applications.

Google Directions API offered by Google is a platform that allows the route calculation from a point of origin and destination through an HTTP request and the map display using Google Maps.

Usage Limits

The use of Google Directions API is subject to a limit of 2,500 requests consultations routes per day. Each route search counts as a single request in his daily quota when the mode of transport is driving, walking or cycling. Search routes with public transport is counted as four requests.

Individual requests for driving directions, walk or cycle may contain up to eight intermediate reference points in the request. Customers of the Google Maps API for Business can see up to 100,000 requests routes per day, with up to 23 reference points allowed in each request. The reference points are not available for public transport routes.

Furthermore, Google Directions API URLs are limited to 2048 characters prior to encoding of the URL. As some of Google Directions API service URLs may involve many locations along a path, consider this limit when creating URLs.

Creating an application using the Google Directions API

To create an application using the Google Directions API you need first to obtain a passkey to be incorporated into the application you want to make use of the API. Obtaining the key is made totally free of charge.

To create an Android application using the Google Directions API you'll need IDE Eclipse Kepler with Android SDK and ADT plugin.

To create a new Android project, click the right button in the Package Explorer and go to the New > Other> Android Application Project, as shown in Figure 1.

Creating a new Android project

Figure 1. Creating a new Android project.

Creating the main activity

On Android, the term activity serves to designate a screen that is shown to the end user, and this consists of two artifacts screen:

  • An XML file containing the screen layout itself;
  • A Java class that controls the state of activity.

The code of the XML file layout is shown in Listing 1 and consists of two text boxes for entering the data source and destination, respectively, and a button to trigger the execution of the design of the route. The initial application screen is shown in Figure 2.

The application home screen.

Figure 2. The application home screen.

The root component file is a component of LinearLayout type with the property android:orientation defined as "vertical". This setting tells Android that the components are positioned one below the other.

Listing 1. main application Activity.

            
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:padding="10dp" >
   
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="0dp"
          android:layout_weight="3"
          android:orientation="horizontal" >
   
          <TextView
              android:text="From"
              android:layout_width="0dp"
              android:layout_weight="1"
              android:layout_height="wrap_content"
              android:textStyle="bold" />
   
          <EditText
              android:id="@+id/editFrom"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="2"
              android:inputType="text"
              android:lines="1"
              android:maxLines="1" />
   
       </LinearLayout>
   
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="0dp"
          android:layout_weight="3"
          android:orientation="horizontal" >
   
          <TextView
              android:text="To"
              android:layout_width="0dp"
              android:layout_weight="1"
              android:layout_height="wrap_content"
              android:textStyle="bold" />
   
          <EditText
              android:id="@+id/editTo"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="2"
              android:inputType="text"
              android:lines="1"
              android:maxLines="1" />
   
      </LinearLayout>
   
      <Button
          android:id="@+id/btnGo"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:text="Go" />
   
  </LinearLayout>

The code of the manager class of the Activity is shown in Listing 2. This class is responsible for retrieving the values of the components defined in the layout file. The validation of the source and destination fields is performed, and if these are correctly filled, navigation will be delegated to the MapActivity class, responsible for the map displaying.

The screen change on an Android application is performed using a component of Intent type. An Intent is a class in this standard Android API that allows navigation between Activities and passing parameters between Activities using putExtra() method.

Listing 2. Activity Principal.

  import android.app.Activity;
  import android.content.Intent;
  import android.os.Bundle;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.Toast;
   
  public class MainActivity extends Activity {
        
      private EditText editFrom;
      private EditText editTo;
      private Button btnGo;
     
      @Override
      protected void onCreate(final Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
         
          editFrom = (EditText) findViewById(R.id.editFrom);
          editTo = (EditText) findViewById(R.id.editTo);
          btnGo = (Button) findViewById(R.id.btnGo);
   
          btnGo.setOnClickListener(new OnClickListener() {
              /**
              * {@inheritDoc}
              */
              @Override
              public void onClick(final View v) {
                  if("".equals(editFrom.getText().toString().trim())) {
                      Toast.makeText(MainActivity.this, "Enter the starting point", Toast.LENGTH_SHORT).show();
                  }
                  else if("".equals(editTo.getText().toString().trim())) {
                      Toast.makeText(MainActivity.this, "Enter the destination point", Toast.LENGTH_SHORT).show();
                  }
                  else {
                      final Intent intent = new Intent(MainActivity.this, MapActivity.class);
                      intent.putExtra("FROM", editFrom.getText().toString().trim());
                      intent.putExtra("TO", editTo.getText().toString().trim());
   
                      MainActivity.this.startActivity(intent);
                  }              
              }
          });
      }
  }

Retrieving and displaying the map parameters

The code of MapActivity class is shown in Listing 3. This class is responsible for retrieving the source and destination values through getStringExtra() method as well as recover the fragment defined in the activity responsible for the map displaying, shown in Listing 4.

Listing 3. Class responsible for managing the map screen

import android.app.Activity;
  import android.os.Bundle;
  import com.google.android.gms.maps.GoogleMap;
  import com.google.android.gms.maps.MapFragment;
   
  public class MapActivity extends Activity {
         private GoogleMap gMap;
         
         @Override
         protected void onCreate(final Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_map);
   
            gMap= ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
   
             final String editFrom = getIntent().getStringExtra("FROM");
             final String editTo = getIntent().getStringExtra("TO");
   
             new RotaTask(this, gMap, editFrom, editTo).execute();
         }
  }

Listing 4. layout screen for map.

<?xml version="1.0" encoding="utf-8"?>
  <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.google.android.gms.maps.MapFragment"/>

The map with the planned route is shown in Figure 3.

Route drawn on Google Maps.

Figure 3. Route drawn on Google Maps.

Using Fragments and MapFragment class

Since its version 3.0, Android included in its API fragments feature, which enables drawing the user interface in a more dynamic and reusable way, in order to support different screen sizes.

A fragments example would be a news application. In a tablet, we would have a screen on the left fragment containing a news listing. By clicking on a list item, would be made available another fragment of the first side containing the details of the chosen news. In a smaller screen size device such as a cell, the detail of the selected fragment news occupy the entire space of the screen, as outlined in Figure 5.

Fragments on Android.

Figure 4. Fragments on Android.

The simplest way to embed a map in an Android application is creating a fragment of type MapFragment. The MapFragment class is a special kind of view in the Google Maps API which acts as a template for rendering the map in the application.

The GoogleMap class is responsible for managing the map display in the application. In it we find the methods responsible for adding interactivity to our map. An instance of this class is obtained by calling the getMap() method of an object of MapFragment class in the application.

Using AsyncTasks

On Android, if not specified any competition, all the code is run on the main thread. This thread is known as UI Thread, also called main() thread.

This becomes a problem in the case of the existence of processes that take a long time to run, because if any processing that takes longer than five seconds the UI thread will stop responding and the application will present an ANR (Application Not Responding) to the user.

One way to work around this problem is through the use of AsyncTasks, which are nothing more than objects that encapsulate and make it transparent to the developer to use threads, allowing the developer to perform operations in the background without Threads API knowledge from the Java platform.

In our example, the code responsible for sending the HTTP request to the Google Directions API is encapsulated in a AsyncTask because given that this is a potentially costly process for the application, do not run the risk of "lock" the main application thread waiting by an API response. The code of AsyncTask class is shown in Listing 5.

Listagem 5. AsyncTask class

//imports omitted...
   
  public class RotaTask extends AsyncTask<Void, Integer, Boolean> {
   
    private static final String TOAST_MSG = "Calculating";
    private static final String TOAST_ERR_MAJ = "Impossible to trace Itinerary";
   
    private Context context;
    private GoogleMap gMap;
    private String editFrom;
    private String editTo;
    private final ArrayList<LatLng> lstLatLng = new ArrayList<LatLng>();
   
    public RotaTask(final Context context, final GoogleMap gMap, final String editFrom, final String editTo) {
        this.context = context;
        this.gMap= gMap;
        this.editFrom = editFrom;
        this.editTo = editTo;
    }
   
    /**
    * {@inheritDoc}
    */
    @Override
      protected void onPreExecute() {
        Toast.makeText(context, TOAST_MSG, Toast.LENGTH_LONG).show();
    }
   
    /***
    * {@inheritDoc}
    */
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            final StringBuilder url = new StringBuilder("http://maps.googleapis.com/maps/api/directions/xml?sensor=false&language=pt");
            url.append("&origin=");
            url.append(editFrom.replace(' ', '+'));
            url.append("&destination=");
            url.append(editTo.replace(' ', '+'));
   
            final InputStream stream = new URL(url.toString()).openStream();
   
            final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setIgnoringComments(true);
   
            final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
   
            final Document document = documentBuilder.parse(stream);
            document.getDocumentElement().normalize();
   
            final String status = document.getElementsByTagName("status").item(0).getTextContent();
            if(!"OK".equals(status)) {
                return false;
            }
   
            final Element elementLeg = (Element) document.getElementsByTagName("leg").item(0);
            final NodeList nodeListStep = elementLeg.getElementsByTagName("step");
            final int length = nodeListStep.getLength();
   
            for(int i=0; i<length; i++) {        
                final Node nodeStep = nodeListStep.item(i);
   
                if(nodeStep.getNodeType() == Node.ELEMENT_NODE) {
                    final Element elementStep = (Element) nodeStep;
             decodePolylines(elementStep.getElementsByTagName("points").item(0).getTextContent());
                }
            }
   
            return true;          
        }
        catch(final Exception e) {
            return false;
        }
    }
   
    private void decodePolylines(final String encodedPoints) {
        int index = 0;
        int lat = 0, lng = 0;
   
        while (index < encodedPoints.length()) {
            int b, shift = 0, result = 0;
   
            do {
                b = encodedPoints.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
   
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;
   
            do {
                b = encodedPoints.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
   
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;
   
            lstLatLng.add(new LatLng((double)lat/1E5, (double)lng/1E5));
        }
    }
   
    /**
    * {@inheritDoc}
    */
    @Override
    protected void onPostExecute(final Boolean result) { 
        if(!result) {
            Toast.makeText(context, TOAST_ERR_MAJ, Toast.LENGTH_SHORT).show();
        }
        else {
            final PolylineOptions polylines = new PolylineOptions();
            polylines.color(Color.BLUE);
   
            for(final LatLng latLng : lstLatLng) {
                    polylines.add(latLng);
            }
   
            final MarkerOptions markerA = new MarkerOptions();
            markerA.position(lstLatLng.get(0));
            markerA.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
   
            final MarkerOptions markerB = new MarkerOptions();
            markerB.position(lstLatLng.get(lstLatLng.size()-1));
            markerB.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
   
            gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lstLatLng.get(0), 10));
            gMap.addMarker(markerA);
            gMap.addPolyline(polylines);
            gMap.addMarker(markerB); 
        }
    }
  }

Now, just run the application and everything will be working fine.

Conclusion

This article aims to introduce the reader into the world of geo-referenced applications, using the famous Google Maps API to show a simple example of calculation and display of routes. We hope with this article have aroused in the reader's curiosity and interest in deepening knowledge in this fantastic area of mobile computing.



Julio is a System analyst and enthusiast of Information Technology. He is currently a developer at iFactory Solutions company, working in the development of strategic systems, is also a JAVA instructor. He has knowledge and experi...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login