# Voice download

Last updated:

<!-- -->

October 18, 2026

<!-- -->

\| 2 minutes read

<br />

<br />

In this guide, you will learn how to list the voice downloads available on the server, how to download a voice, and track the download progress.

## How it works[​](#how-it-works "Direct link to How it works")

The example app demonstrates the following features:

* Get a list of available voices
* Download a voice

![Initial map screen](/docs/flutter/assets/images/example_flutter_voice_download1-1d65465e7eda8a4bab45e13e33a7ea55.png)

**Initial map screen**

![Downloaded multiple voices](/docs/flutter/assets/images/example_flutter_voice_download2-c4ee8cd6c2107417319ba068246004c5.png)

**Downloaded multiple voices**

### Initialize the Map[​](#initialize-the-map "Direct link to Initialize the Map")

This callback function is called when the interactive map is initialized and ready to use. Allows mobile data usage for content downloads.

main.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/main.dart?ref_type=heads#L68)

```dart

  void _onMapCreated(GemMapController controller) async {
    SdkSettings.setAllowOffboardServiceOnExtraChargedNetwork(
      ServiceGroupType.contentService,
      true,
    );
  }

```

### Navigate to Voices Page[​](#navigate-to-voices-page "Direct link to Navigate to Voices Page")

A tap on the voice icon in the app bar calls this method to navigate to the voice download screen.

main.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/main.dart?ref_type=heads#L75)

```dart

  // Method to navigate to the Voices Page.
  void _onVoicesButtonTap(BuildContext context) async {
    Navigator.of(context).push(
      MaterialPageRoute<dynamic>(builder: (context) => const VoicesPage()),
    );
  }

```

### Retrieve List of Voices[​](#retrieve-list-of-voices "Direct link to Retrieve List of Voices")

The list of voices available for download is obtained from the server using ContentStore.asyncGetStoreContentList(ContentType.voice).

voices\_page.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/voices_page.dart?ref_type=heads#L63)

```dart
  Future<List<ContentStoreItem>> _getVoices() {
    Completer<List<ContentStoreItem>> voicesList =
        Completer<List<ContentStoreItem>>();
    ContentStore.asyncGetStoreContentList(ContentType.humanVoice, (
      err,
      items,
      isCached,
    ) {
      if (err == GemError.success && items.isNotEmpty) {
        voicesList.complete(items);
      }
    });
    return voicesList.future;
  }

```

### Display Voices[​](#display-voices "Direct link to Display Voices")

The voices are displayed in a list, and a CircularProgressIndicator is shown while the voices are being loaded.

voices\_page.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/voices_page.dart?ref_type=heads#L39)

```dart
      body: FutureBuilder<List<ContentStoreItem>>(
        future: _getVoices(),
        builder: (context, snapshot) {
          if (!snapshot.hasData || snapshot.data == null) {
            return const Center(child: CircularProgressIndicator());
          }
          return Scrollbar(
            child: ListView.separated(
              padding: EdgeInsets.zero,
              itemCount: snapshot.data!.length,
              separatorBuilder: (context, index) =>
                  const Divider(indent: 50, height: 0),
              itemBuilder: (context, index) {
                final voice = snapshot.data!.elementAt(index);
                return VoicesItem(voice: voice);
              },
            ),
          );
        },

```

### Download Voice[​](#download-voice "Direct link to Download Voice")

This method initiates the voice download.

voices\_item.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/voices_item.dart?ref_type=heads#L145)

```dart

  void _downloadVoice() {
    // Download the voice.
    widget.voice.asyncDownload(
      _onVoiceDownloadFinished,
      onProgress: _onVoiceDownloadProgressUpdated,
      allowChargedNetworks: true,
    );
  }

```

### Retrieve Country Flag[​](#retrieve-country-flag "Direct link to Retrieve Country Flag")

This method retrieves the flag image for each voice.

voices\_item.dart[View on Github](https://github.com/magiclane/magiclane-maps-sdk-examples-for-flutter/tree/main/voice_download/lib/voices_item.dart?ref_type=heads#L129)

```dart
  Img? _getCountryImage(ContentStoreItem voice) {
    final countryCodes = voice.countryCodes;
    final countryImage = MapDetails.getCountryFlagImg(countryCodes[0]);
    return countryImage;
  }

```
