Nav SDK - Headless mode

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.

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.

alt_text alt_text
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:

alt_text alt_text
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.