The MapQuest Navigation SDK enables turn-by-turn GPS in any iOS or Android application. Developers now have the ability to customize their UI and gain insight into the navigation experience as users drive.
The SDK provides:
build.gradle
file
-- such that it includes the maven URL for the MapQuest artifacts repository:
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
maven {
url "http://artifactory.cloud.mapquest.com/artifactory/et-android-binaries"
}
}
}
dependencies
section of the build.gradle
file for the app:
dependencies {
compile('com.mapquest:navigation:3.1.0') // the MapQuest Navigation SDK
compile('com.mapzen.android:lost:3.0.2') // used for Location Acquisition (GPS)
// note: the MapQuest Mapping SDK (i.e. "MapView") used to display our route to navigate
compile('com.mapquest:mapping-android-sdk:1.6.3') {
exclude group: 'com.android.support'
}
compile("com.mapquest:search-ahead-v3:1.2.9") // for the MapQuest "Search Ahead" feature (optional)
}
In order to use MapQuest APIs and SDKs you will need a MapQuest key. We use this key to associate your requests to APIs with your account. You can find your existing keys or create a new one on the Applications page.
If you don't have a MapQuest Developer Account you can Sign Up Here.
Once you have a MapQuest Key, per above, create a new file named mapquest.properties
in the app
directory
of your project, containing the following single-line entry:
api_key=[PUT_YOUR_API_KEY_HERE]
Then, add the following items under the `android` section of the build.gradle
file for the app:
applicationVariants.all { variant ->
variant.buildConfigField "String", "API_KEY", getApiKey() // Provides key for the Navigation SDK
variant.resValue "string", "API_KEY", getApiKey() // Provides key for the MapView used in app layouts
}
Per the above, also add the following method (at the top-level) to the build.gradle
for the app -- to define the getApiKey()
method:
def getApiKey() {
def props = new Properties()
file("mapquest.properties").withInputStream { props.load(it) }
return "\"" + props.getProperty("api_key") + "\""
}
Before adding any of the example code outlined below, try building your app thus far -- to ensure that the above setup and library dependencies are indeed correct.
In general, developers using the Navigation SDK will first create a query against the RouteService
,
and then call the method startNavigation
on the returned route -- using an instance of the NavigationManager
which captures callbacks for navigation-related events. Events are triggered when:
Here's a simple example of how to create a route from New York City to Boston, and then start a turn-by-turn navigation session.
First, we create an instance of the RouteService
, using our API_KEY
, like so:
mRouteService = new RouteService.Builder().build(getApplicationContext(), BuildConfig.API_KEY);
Additionally, we'll also need an instance of NavigationManager
, which we will use to navigate the route
selected after it has been retrieved -- note that it requires a LocationProviderAdapter
(discussed further below):
mNavigationManager = new NavigationManager.Builder(this, BuildConfig.API_KEY)
.withLocationProviderAdapter(mApp.getLocationProviderAdapter())
.build();
Now, we can define a start and destination(s) for the route --
and query the RouteService
for the possible route(s) between these locations -- specifying various RouteOptions
as desired (e.g. to allow toll-roads, disallow ferries, etc):
// Set up start and destination for the route
Coordinate nyc = new Coordinate(40.7326808, -73.9843407);
List boston = Arrays.asList(new Coordinate(42.355097, -71.055464));
// Set up route options
RouteOptions routeOptions = new RouteOptions.Builder()
.maxRoutes(3)
.highways(RouteOptionType.ALLOW)
.tolls(RouteOptionType.ALLOW)
.ferries(RouteOptionType.DISALLOW)
.internationalBorders(RouteOptionType.DISALLOW)
.unpaved(RouteOptionType.DISALLOW)
.seasonalClosures(RouteOptionType.AVOID)
.build();
mRouteService.requestRoutes(nyc, boston, routeOptions, new RoutesResponseListener() {
@Override
public void onRoutesRetrieved(List routes) {
if (routes.size() > 0) {
mNavigationManager.startNavigation((Route) routes.get(0));
}
}
@Override
public void onRequestFailed(@Nullable Integer httpStatusCode, @Nullable IOException exception) {}
@Override
public void onRequestMade() {}
});
Note that in the onRoutesRetrieved
callback, above,
we use our NavigationManager
to startNavigation
on, say, the first Route
that was retrieved --
though in a real application we might first "render" the resulting routes on a map-view, and allow the user to select
the one they wish to navigate.
Refer to the Navigation SDK Reference Sample Application code to see a complete example of how to
leverage the MapQuest Android SDK (MapView) to draw the routes returned from the RouteService
.
Now that you have the basics in place -- using the RouteService
and using the NavigationManager
to start navigation
along a selected route -- the next step is to leverage one or more of the available callbacks provided by various listener interfaces,
provided in the SDK package: com.mapquest.navigation.listener
.
Simply define an implementation of a given listener interface, and implement the desired functionality for each callback method of interest.
For example, if we want to simply update a message in the UI to inform the user that navigation has started or stopped, we can implement a
NavigationStartStopListener
, and add it to our NavigationManager
instance, like so:
mNavigationManager.addAndNotifyNavigationStartStopListener(new NavigationStartStopListener() {
@Override
public void onNavigationStarted() {
Toast.makeText(mApp, "Navigation Started...", Toast.LENGTH_SHORT).show();
}
@Override
public void onNavigationStopped(@NonNull RouteStoppedReason routeStoppedReason) {
Toast.makeText(mApp, "Navigation Stopped.", Toast.LENGTH_SHORT).show();
}
});
Another commonly used listener is the EtaResponseListener
, used to update the UI when the Estimated Time of Arrival has changed while navigating a route.
For example, you could add one like so:
mNavigationManager.addEtaResponseListener(new EtaResponseListener() {
@Override
public void onEtaUpdate(@NonNull EstimatedTimeOfArrival estimatedTimeOfArrival) {
// TODO: update your ETA (text) view here...
}
});
The complete set of available listeners are described in detail in the Navigation SDK API Docs, and include:
When navigating a route using the NavigationManager
, the user's location updates are provided to the SDK
by a location provider. The abstract class LocationProviderAdapter
in the SDK provides a generic "wrapper" for any
location-provider of your choice -- for example, a native Google location service, a "mocked" location-provider
(e.g. used during testing), or one of the commonly used 3rd-party location libraries such as
Mapzen Lost.
The Navigation SDK Reference Sample Application provides an example implementation using the Mapzen Lost location
provider library, MapzenLocationProviderAdapter
-- refer to the documentation
for more details on the LocationProviderAdapter
and the implementation of MapzenLocationProviderAdapter
.