.NET MAUI Android Auto : Launching Navigation Apps from your app

Android Auto is a popular platform that allows users to seamlessly integrate their Android devices with their car’s infotainment system. This integration extends to navigation, allowing users to launch navigation apps like Google Maps or Waze directly from Android Auto. In this blog post, we’ll explore how to achieve this functionality from within your Android application using .NET MAUI.

The key to launching navigation apps on Android Auto is to construct a URI with the desired latitude and longitude and use an Intent to open the navigation app. Let’s break down the code snippet you provided to understand how it works:

public class NavigationOnClickListener : Java.Lang.Object, IOnClickListener
{
    private readonly CarContext _context;
    private readonly double _latitude;
    private readonly double _longitude;

    public NavigationOnClickListener(CarContext context, double latitude, double longitude)
    {
        _context = context;
        _latitude = latitude;
        _longitude = longitude;
    }

    public void OnClick()
    {
        string uri = $"geo:{_latitude.ToString(CultureInfo.InvariantCulture)},{_longitude.ToString(CultureInfo.InvariantCulture)}";
        Intent intent = new Intent(CarContext.ActionNavigate)
            .SetData(AndroidUri.Parse(uri));
        _context.StartCarApp(intent);
    }
}

AndroidUri is the Android.Net.Uri class alias achieved by:

using AndroidUri = Android.Net.Uri;

Let’s dissect this code step by step:

  1. NavigationOnClickListener is a custom class that implements the IOnClickListener interface. This class is responsible for handling the click event that launches the navigation app.
  2. In the constructor, we receive three parameters: context, latitude, and longitude. context is the CarContext instance, and latitude and longitude are the destination coordinates (double).
  3. Inside the OnClick method, we construct a URI in the following format: "geo:latitude,longitude". The CultureInfo.InvariantCulture is used to ensure that the decimal separator is a period (.) rather than a comma (,) to make the URI universally compatible. This is crucial because different regions may use different formats for numbers.
  4. We create an Intent with the action CarContext.ActionNavigate. This action specifies that we want to launch a navigation app.
  5. We set the data of the intent by parsing the constructed URI using AndroidUri.Parse(uri).
  6. Finally, we start the navigation app by invoking _context.StartCarApp(intent).
This content has 6 months. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.

.NET MAUI Android Auto: Async loading of lists

Android Auto has become an integral part of the modern driving experience, allowing users to access important information and features without taking their eyes off the road. In this blog post, we’ll explore how to implement asynchronous loading of lists in Android Auto to ensure a smooth and responsive user experience.

If you are new how to implement Android Auto in your .NET MAUI Application, then scroll to the very end of this post, and you will find a detailed tutorial video by Christian Strydom how to do it.

Implementation

Let’s assume that we have a class with a list of SomeObject named _allItems.
This list contains the data we want to display in an Android Auto list. If you dont have this private field of List<SomeObject> in your Android Auto Screen class, then define it like this: ‘private List<SomeObject> _allItems;’

We’ll use the OnGetTemplate method to check whether _allItems has data. If it doesn’t, we’ll start an asynchronous task to load the data and show a loading indicator. If it does, we’ll build the list with the existing data.

OnGetTemplate modify

In the OnGetTemplate method, we’ll first create a ListTemplateBuilder and check if _allItems has data:

public override ITemplate OnGetTemplate()
{
    var listTemplateBuilder = new ListTemplate.Builder();

    if (_allItems?.Any() != true)
    {
        // Start an async task to load data
        _ = LoadData();

        // Show a loading indicator
        return listTemplateBuilder.SetLoading(true).Build();
    }
    
    // Build the list using the existing data
    var items = BuildListItems(_allItems);
    listTemplateBuilder.AddItems(items);

    return listTemplateBuilder.Build();
}

Implement the Async Task

Now, let’s create an asynchronous task, LoadDataAsyncTask, which will invoke a method asynchronously to fetch and set the value of _allItems. We will use a hypothetical API call as an example:

    private async Task LoadData()
    {
        try
        {
            // Perform an asynchronous operation (e.g., an API call)
            var result = await SomeApiCallAsync(); // Replace with your actual API call

            // Set the value of _allItems with the result
            _allItems = result;
        }
        catch (Exception e)
        {
            // Handle exceptions and show a CarToast
            CarToast.MakeCarToast(CarContext , "An error occurred", CarToast.DurationLong).Show();
        }
        finally
        {
            // Ensure that the UI is invalidated
            // This will trigger the OnGetTemplate again.
            Invalidate();
        }
    }

Implementing asynchronous loading of lists in Android Auto ensures that your app remains responsive and user-friendly. By following this approach, you can fetch and display data efficiently, handle exceptions gracefully, and maintain a smooth user experience while driving. Android Auto provides a powerful platform for developers to create safe and engaging automotive experiences, and proper asynchronous loading is a key part of that experience.

This content has 6 months. Some of the information in this post may be out of date or no longer work. Please, read this page keeping its age in your mind.