Android Tutorial: Open Navigation for Google Maps, Waze, and HERE WeGo

Michael Ganchas
The Startup
Published in
4 min readSep 18, 2020
Image from https://www.manypixels.co/gallery/

Hi all!

Today I’d like to share with you how I use intents to launch some of the most popular navigations apps from my own Android app.

First of all, you should identify your own requirements, and ask yourself the following questions:

  • Do I want/need to implement navigation inside my app?
  • Is it ok if my app only redirects the user to other navigation specific apps?

If you find yourself in the first scenario, then perhaps this is not the tutorial for you, for that situation. But, if you need help implementing for the second one, then keep on reading.

The navigation apps

I chose Google Maps, Waze, and HERE WeGo because they seemed like the most commonly used apps for this purpose. I’m sure there are plenty of others out there that are just as great (or better).

The code

I usually separate these sorts of utility classes by their domain or usability (e.g. directions, sharing, permissions, file processing, etc).

So we create a new file called “DirectionsApi”, where we’ll put our code to handle all the parts related to opening those navigation apps.

Note: For curiosity purposes, it isn’t called “NavigationApi” because I usually have a class named like that for in-app navigation (between activities, fragments).

You should now have a file like this (if using Kotlin):

class DirectionsApi {
}

Since we want this to be available statically (and not instanced each time we need it), let’s add a companion object block to it:

class DirectionsApi {
companion object {

}
}

Now, for two of the selected apps (Waze and HERE WeGo), we can only navigate from where we are to a destination point, whereas in Google Maps you can set it up to navigate from any place (even if you’re not there) to any intended destination.

Waze

Let’s start by adding the code for Waze.

fun openWazeNavigationToB(context: Context, 
latitude : Double,
longitude : Double)
{
val wazeUrl = "https://waze.com/ul?ll=$latitude%2C$longitude&navigate=yes"
val uri = Uri.parse(wazeUrl)

val intent = Intent(Intent.ACTION_VIEW, uri)
context.startActivity(intent)
}

So we need to receive the app’s context, the destination latitude, and longitude. If you have the coordinates in a different format (Location, LatLng, etc) just create overloads for each format or adjust this method accordingly.

We take the URL that Waze knows how to handle, put the latitude and longitude where they should inside it; then, we launch an intent and wait for the intent app chooser to show Waze (if it’s installed in the phone) and select it. That’s it.

HERE WeGo

For HERE WeGo, the logic is the same as with Waze, with the exception that we need to specify the intent package to use.

fun openHereWeGoNavigationToB(context: Context,
latitude : Double,
longitude : Double)
{
val hereWeGoUrl = "here.directions://v1.0/mylocation/$latitude,$longitude?m=w"
val uri = Uri.parse(hereWeGoUrl)

val hereWeGoPackage = "com.here.app.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(hereWeGoPackage)
}
context.startActivity(intent)
}

For scope functions (the apply operator), please check the official documentation.

Google Maps

For Google Maps, as said previously, we can use either A-to-B or Here-to-B.

Here-to-B:

fun openGoogleMapsNavigationToB(context: Context,
latitude : Double,
longitude : Double)
{
val googleMapsUrl = "google.navigation:q=$latitude,$longitude"
val uri = Uri.parse(googleMapsUrl)

val googleMapsPackage = "com.google.android.apps.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(googleMapsPackage)
}

context.startActivity(intent)
}

As with HERE WeGo, we also need to specify the intent package.

A-to-B

fun openGoogleMapsNavigationFromAToB(context: Context,
originLatitude : Double,
originLongitude : Double,
destinationLatitude : Double,
destinationLongitude : Double)
{
val googleMapsUrl = "https://www.google.com/maps/dir/?api=1&" +
"origin=$originLatitude," +
"$originLongitude&" +
"destination=$destinationLatitude," +
"$destinationLongitude"
val uri = Uri.parse(googleMapsUrl)

val googleMapsPackage = "com.google.android.apps.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(googleMapsPackage)
}

context.startActivity(intent)
}

Here, the URL accepts more parameters in it, so we can add both the origin and destination coordinates for Google Maps to interpret.

That’s it! The final class should look like this:

import android.content.Context
import android.content.Intent
import android.net.Uri

class DirectionsApi
{
companion object
{
fun openWazeNavigationToB(context: Context,
latitude : Double,
longitude : Double)
{
val wazeUrl = "https://waze.com/ul?ll=$latitude%2C$longitude&navigate=yes"
val uri = Uri.parse(wazeUrl)

val intent = Intent(Intent.ACTION_VIEW, uri)
context.startActivity(intent)
}

fun openHereWeGoNavigationToB(context: Context,
latitude : Double,
longitude : Double)
{
val hereWeGoUrl = "here.directions://v1.0/mylocation/$latitude,$longitude?m=w"
val uri = Uri.parse(hereWeGoUrl)

val hereWeGoPackage = "com.here.app.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(hereWeGoPackage)
}

context.startActivity(intent)
}

fun openGoogleMapsNavigationToB(context: Context,
latitude : Double,
longitude : Double)
{
val googleMapsUrl = "google.navigation:q=$latitude,$longitude"
val uri = Uri.parse(googleMapsUrl)

val googleMapsPackage = "com.google.android.apps.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(googleMapsPackage)
}

context.startActivity(intent)
}

fun openGoogleMapsNavigationFromAToB(context: Context,
originLatitude : Double,
originLongitude : Double,
destinationLatitude : Double,
destinationLongitude : Double)
{
val googleMapsUrl = "https://www.google.com/maps/dir/?api=1&" +
"origin=$originLatitude," +
"$originLongitude&" +
"destination=$destinationLatitude," +
"$destinationLongitude"
val uri = Uri.parse(googleMapsUrl)

val googleMapsPackage = "com.google.android.apps.maps"
val intent = Intent(Intent.ACTION_VIEW, uri).apply {
setPackage(googleMapsPackage)
}

context.startActivity(intent)
}
}
}

Feel free to ask any questions or add suggestions if you’d like!

Cheers!

--

--