Introduction
Navigation SDK (Nav SDK) provides a best in class turn-by-turn feature that can be very helpful to customers and drivers, especially new drivers or drivers who are not familiar with the region. However, there are specific use cases where companies do not want to take drivers' attention out of the road with turn-by-turn navigation UI, but still want to track vehicle locations and listen to events related to the route they are following. One example are truck drivers, especially if they are transporting hazard materials. Other companies doing deliveries using different modalities - such as walking for short distances - might not require turn-by-turn enabled as well and this would save the device’s battery life.
Scope
This document describes how companies can hide the Navigation map (view) from Nav SDK and still benefit from all the features of Nav SDK in regards to location tracking, event subscriptions and callbacks. Data captured from the Nav SDK in headless mode can be used to improve the capability to track vehicles and understand ETAs more precisely which ultimately leads to transparency and efficiency.
Navigation SDK
The Navigation SDK is a native Android / iOS library that is added to the driver app. In the context of mobility, it is responsible for:
- Obtaining road snapped locations from the app running it. Road-snapped locations are more precise than Android’s FusedLocationProvider (FLP), as it uses Google’s road network to snap locations to the nearest road segment, which makes ETAs and other information from FLP much more accurate.
- Turn-by-turn experience which allows drivers to get efficiently from point A to point B taking into account real-time traffic and other route restrictions.
- Firing events based on route progress, location, speed, etc. through event listeners and registered callbacks.
Default experience
When customers implement Nav SDK, it is assumed that they need the turn-by-turn feature. That’s why the Nav SDK’s documentation (Android and iOS) provides instructions on how to implement Nav SDK with turn-by-turn enabled.
On Android rendering the turn-by-turn map in the app is achieved by using a SupportNavigationFragment or NavigationView, whereas on iOS it is a GMSMapView. These UI elements add the interactive map and turn-by-turn navigation UI to your app.
In the next section, we compare the default Nav SDK with turn-by-turn enabled code with the headless Nav SDK code for both Android and iOS, highlighting the changes required.
Solution
Android
On Android, this is the Java code that comes as part of the Nav SDK sample app.
@Override
@SuppressLint("MissingPermission")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Obtain a reference to the NavigationFragment
setContentView(R.layout.activity_nav_fragment);
mNavFragment = (SupportNavigationFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_fragment);
As you can see, the view points to the layout that should be used to draw the navigation experience and, in this case, a SupportNavigationFragment is created rather than the NavigationView.
To make Nav SDK start on headless mode, we simply have to remove those two instructions. If the idea is to toggle between headless and non-headless (active navigation), a variable can be used to determine whether headless must or not be used, for example:
Boolean mHeadless = true;
Then it can be later used, like this:
@Override
@SuppressLint("MissingPermission")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Obtain a reference to the NavigationFragment
if(!mHeadless) {
setContentView(R.layout.activity_nav_fragment);
mNavFragment =
(SupportNavigationFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_fragment);
}
The mHeadless
variable can be linked to an UI component (ie. toggle) that will enable or disable headless accordingly.
![]() |
![]() |
Nav SDK running with active navigation (headless off) | Same app but now with Nav SDK running in headless mode |
As you can see on the right example above, Nav SDK navigation is running under the scenes but the turn-by-turn experience is disabled.
iOS
On iOS headless mode can be done very easily by adding the following setting during the MapView initialization: \
mapView.isHidden = true
For example:
/// The main map view.
private lazy var mapView: GMSMapView = {
let mapView = GMSMapView(frame: .zero)
mapView.isHidden = true /// Make it headless!
mapView.isNavigationEnabled = true
mapView.settings.compassButton = true
mapView.delegate = self
return mapView
}()
See how it would look like - the screen will depend on the way the UI is implemented and the screenshot is just to illustrate the effect of hiding the mapView:
![]() |
![]() |
Active navigation running on
iOS sample app |
Same app in headless mode |
Implementation Considerations
As headless mode is nothing more than hiding the navigation map from the screen, only screen time is saved which yields more battery time on the device. However, as Nav SDK will continue to run, location updates and all event callbacks will be triggered normally, therefore there is no side effect in using this configuration.
Conclusion
This document shows how flexible Nav SDK is and what we can achieve in different operating systems given their restrictions. It also allows customers to customize their driver experience to avoid distractions and improve safety.
Additional Resources
If notifications must be disabled during navigation, due to the reasons aforementioned, this can also be achieved, please refer to Modify turn by turn notifications in Nav SDK.