Voice Download¶
Setup¶
Prerequisites¶
Build and Run¶
Start a terminal/command prompt and navigate to the voice_download
directory,
within the Flutter examples directory - that is the name of this example project.
Note - the gem_kit
directory containing the Maps SDK for Flutter
should be in the plugins
directory of the example, e.g.
example_pathname/plugins/gem_kit
- see the environment setup guide above.
Run: flutter pub get
Configure the native parts:
First, verify that the ANDROID_SDK_ROOT
environment variable
is set to the root path of your android SDK.
In android/build.gradle
add the maven
block as shown,
within the allprojects
block, for both debug and release builds:
allprojects {
repositories {
google()
mavenCentral()
maven {
url "${rootDir}/../plugins/gem_kit/android/build"
}
}
}
in android/app/build.gradle
within the android
block, in the defaultConfig
block,
the android SDK version minSdk
must be set as shown below.
Additionally, for release builds, in android/app/build.gradle
,
within the android
block, add the buildTypes
block as shown:
Replace example_pathname
with the actual project pathname
android {
defaultConfig {
applicationId "com.magiclane.gem_kit.examples.example_pathname"
minSdk 21
targetSdk flutter.targetSdk
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
Then run the project:
flutter run --debug
orflutter run --release
App entry and initialization¶
const projectApiToken = String.fromEnvironment('GEM_TOKEN');
void main() {
runApp(const MyApp());
}
This code initializes the projectApiToken with the required authorization token and launches the app.
How It Works¶
The example app demonstrates the following features:
Get a list of available voices
Download a voice
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.
void _onMapCreated(GemMapController controller) async {
SdkSettings.setAllowOffboardServiceOnExtraChargedNetwork(ServiceGroupType.contentService, true);
}
Retrieve List of Voices¶
The list of voices available for download is obtained from the server using
ContentStore.asyncGetStoreContentList(ContentType.voice)
.
Future<List<ContentStoreItem>> _getVoices() async {
Completer<List<ContentStoreItem>> voicesList = Completer<List<ContentStoreItem>>();
ContentStore.asyncGetStoreContentList(ContentType.voice, (err, items, isCached) {
if (err == GemError.success && items != null) {
voicesList.complete(items);
}
});
return voicesList.future;
}
Display Voices¶
The voices are displayed in a list, and a CircularProgressIndicator is shown while the voices are being loaded.
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¶
This method initiates the voice download.
void _downloadVoice() {
widget.voice.asyncDownload(_onVoiceDownloadFinished,
onProgressCallback: _onVoiceDownloadProgressUpdated, allowChargedNetworks: true);
}
Retrieve Country Flag¶
This method retrieves the flag image for each voice.
Uint8List _getCountryImage(ContentStoreItem voice) {
final countryCodes = voice.countryCodes;
return MapDetails.getCountryFlag(countryCode: countryCodes[0], size: const Size(100, 100));
}