Core
This module is required to use almost all other modules. It handles the BeNomad license validation, the download/deployment of the maps and other required resources. To use it, you need a valid purchase UUID key provided by BeNomad. This unique key will determine which maps (HERE/TomTom/OpenStreetMap..etc.) have to be downloaded and how many installations are allowed. It also define the maps deployment mode (full maps or hybrid maps) and the map coverage.
Almost all modules depends on this module :
Map module
Map Services module
Geocoder module
Planner module
Navigation module
GPS module
Notes: For the first Core initialization, the device must have an Internet connection. Then, the Core must be initialized with an Internet connection before the end of "authorized offline period" (default duration is 30 days). Check The OnOfflinePeriodExpiredCallback to be notified when the offline period has expired for further details.
Module Core
The
OnInitProgressCallbackto get the Core initialization progressThe
OnMapDownloadProgressCallbackto get the progress of the maps downloadThe
OnHybridMapDownloadProgressCallbackto get the progress of the hybrid maps downloadThe
OnMapExtractionProgressCallbackto get the progress of the maps extractionThe
OnLicenseErrorCallbackto be notified about errors with the licenseThe
OnLicenseExpiredCallbackto be notified when the license has expiredThe
OnMapUpdateAvailableCallbackto be notified when a map update is availableThe
OnOfflinePeriodExpiredCallbackto be notified when the offline period has expired
Dependencies
This module depends on other BeNomad's modules :
Error Manager
Other module's dependencies :
implementation "androidx.appcompat:appcompat:1.3.0"
implementation "com.google.android.material:material:1.8.0"
implementation "androidx.core:core-ktx:1.9.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.10"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1"Permissions
On Android platforms < 10 and before starting the module initialization, your Android application must request the READ_PHONE_STATE mandatory permission (It is required for the licensing validation process).
Optionally, the WRITE_EXTERNAL_STORAGE permission may be required if maps have to be deployed outside of the application's scoped storage (only possible for Android platforms < 11).
The application must also declare the INTERNET permission in its Manifest.
We simplified this process in the Permissions Manager module. You can see how to use it in its own documentation. It is not mandatory to use this module.
Core initialization
Here is a sample code that shows how the Core can be initialized :
import kotlinx.coroutines.launch
import androidx.lifecycle.lifecycleScope
import com.benomad.msdk.core.callbacks.OnCoreInit.OnCoreInitCallback
import com.benomad.msdk.core.Core
// Callback used to get the result of the Core initialization
val coreInitCallback = object : OnCoreInitCallback{
override fun onCoreReady() {
//Core initialization is successful
}
override fun onCoreInitError(error: Error) {
//An error occurred during the Core initialization
}
override fun onCoreInitException(exception: Exception) {
//An exception was raised during the Core initialization
}
}
// The READ_PHONE_STATE permission must have been accepted by the user (if the Android version < 10)
//internally launched in a coroutine
Core.getInstance().init(
applicationContext,
purchaseUUID,
mapsDeploymentPath,
resourcesPathInAssets,
mapsPathInAssets,
coreInitCallback
)Here is a description of the init method's arguments :
``applicationContext``: the application context``purchaseUUID``: A BeNomad purchase UUID``mapsDeploymentPath``: the absolute path to deploy the maps to. If the maps are already deployed in the given path, it will be considered as already deployed (the maps won't be downloaded). If no value is passed for this argument, the maps are deployed in a "Maps" folder in the external scoped storage (the "files" folder of the application)``resourcesPathInAssets``: the relative path from the assets folder to the resources folder. Pass null if you don't need to deploy the resources (required to use the Map module)``mapsPathInAssets``: the relative path from the assets to the maps folder to deploy. If you pass null, the maps will be automatically downloaded from the BeNomad servers if no maps resources are found in the given``mapsDeploymentPath````callback``: the``OnCoreInitCallback ``observer that will notify about the Core init result
Please note that specifying a mapsDeploymentPath that is outside of the application's scoped storage only works for versions of Android < 11. You will also need to request the WRITE_EXTERNAL_STORAGE permission before initializing the Core in that case.
We do recommend to use default value for mapsDeploymentPath which is the external scoped storage of the application (in the internal memory of the device). You can get this value with Core.getDefaultMapsPath method.
If you need to deploy map data on an SD card, you need to do it manually before initializing the Core because automatic online map data deployment on an SD card is currently not supported. Check manual update or initial deployment section for further details.
Map data deployment
Automatic online deployment
If no map data is deployed before initializing the Core or during the Core intialization (using mapsPathInAssets argument of the Core.init method), data will automatically be deployed if the device has an internet connection. Note: automatic online map data deployment on an SD card is currently not supported.
Here is how to handle online map data updates :
To be notified about an available map data update, check The
OnMapUpdateAvailableCallbackto be notified when a map update is availableAfter accepting the update, you can use The
OnMapDownloadProgressCallbackto get the progress of the maps downloadTo check if any error occurs during the download, use The
OnMapDownloadErrorCallbackto be notified when an error occurred during the map download, whether it's the original download or an updateTo be notified when the download has finished, use The
OnMapDownloadedCallbackto be notified when the map update is downloaded, or when the initial map data is downloaded
After OnMapDownloadedCallback has been called, the map update will be deployed automatically at the next Core initialization (at next app launch for example, it depends on your implementation). You can use The OnMapExtractionProgressCallback to get the progress of the maps extraction
Manual update or initial deployment
To deploy and update map data manually (from an SD card for example), you simply have to put/replace the map data in the path specified in the Core.init method (mapsDeploymentPath argument) before initializing the Core. Make sure that the deployed map package contains the mapsversion file, otherwise the licensing system will replace the map data that you have deployed.
If you deploy map data on an SD card and your app targets Android 11+, you need to deploy map data in a path that corresponds to the external scoped storage of your application. For example :
If your absolute path to the external scoped storage of your application is : /sdcard/Android/data/com.example.app/files (which also corresponds to : /storage/self/primary/Android/data/com.example.app/files)
You need to use this base path for deploying your map data because it corresponds to the external scoped storage of your application stored on the SD card : /storage/sdcard1/Android/data/com.benomad.basicplanner/files/
You can use the Device File Explorer of Android Studio to get the path to the external scoped storage of your application. As you can see in this example, the path /sdcard/Android/data/ (or /storage/self/primary/Android/) corresponds to the internal memory of the device where applications data is located, and /storage/sdcard1/Android/data/ corresponds to the SD card storage where applications data can be located too.
Observables (callbacks)
There are other observables that you can subscribe to before starting the Core initialization :
The OnInitProgressCallback to get the Core initialization progress
OnInitProgressCallback to get the Core initialization progressUsage :
Core.getInstance().addOnInitProgressObserver(this)
// the observer parameter in this example is the class that implements the OnInitProgressCallback, but it can also be an object variable
override fun onInitProgress(progress: Float) {
// progress is the current global progress of the Core initialization from 0 to 100
}The OnMapDownloadProgressCallback to get the progress of the maps download
OnMapDownloadProgressCallback to get the progress of the maps downloadUsage :
Core.getInstance().addOnMapDownloadProgressObserver(this)
override fun onMapDownloadProgress(progress: Float, downloaded: Float, total: Float) {
//progress is the current progress of the maps download from 0 to 100
//downloaded is the size in KB of the data already downloaded
//total is the total size in KB to download
}The OnHybridMapDownloadProgressCallback to get the progress of the hybrid maps download
OnHybridMapDownloadProgressCallback to get the progress of the hybrid maps downloadNote: This callback is useful only if you're using the hybrid mode for the maps data
Usage :
Core.getInstance().addOnHybridDownloadProgressObserver(this)
override fun onHybridMapDownloadProgress(status: Int, progress: Double) {
//status is the current status of the hybrid download
/**
-3: Not enough storage space,
-2: Internal error,
-1: Download failed (network error),
0: Download started,
1: Download in progress and the percentage is available,
2: Download finished
*/
//progress is the current progress of the maps download from 0 to 100
}The OnMapExtractionProgressCallback to get the progress of the maps extraction
OnMapExtractionProgressCallback to get the progress of the maps extractionUsage :
Core.getInstance().addOnMapExtractionProgressObserver(this)
override fun onMapExtractionProgress(progress: Float) {
//progress is the current progress of the map extraction from 0 to 100
}The OnLicenseErrorCallback to be notified about errors with the license
OnLicenseErrorCallback to be notified about errors with the licenseUsage :
Core.getInstance().addOnLicenseErrorObserver(this)
override fun onLicenseError(error: Error) {
val messageId = error.messageId // the message id of the error
val errorExplanation = error.detailedMessage // a more detailed message about the error (not always available, in this case an empty String is returned)
}The OnLicenseExpiredCallback to be notified when the license has expired
OnLicenseExpiredCallback to be notified when the license has expiredUsage :
Core.getInstance().addOnLicenseExpiredObserver(this)
override fun onLicenseExpired() {
//this is triggered when your license has expired
}The OnMapUpdateAvailableCallback to be notified when a map update is available
OnMapUpdateAvailableCallback to be notified when a map update is availableUsage :
Core.getInstance().addOnMapUpdateAvailableObserver(this)
override fun onMapUpdateAvailable() {
//a map update is available.
Core.getInstance().downloadAvailableUpdate(userChoice) //user choice is a Boolean that indicates if the user accepted the update download or refused it.
}Note : To be notified about the update download progress, use OnMapDownloadProgressCallback which is the same callback used for the maps download progress.
The OnMapDownloadedCallback to be notified when the map update is downloaded, or when the initial map data is downloaded
OnMapDownloadedCallback to be notified when the map update is downloaded, or when the initial map data is downloadedUsage :
Core.getInstance().addOnMapDownloadedObserver(this)
override fun onMapDownloaded() {
//the initial map download or the map update download has finished. In case of an update, it will be installed on next application start
}The OnMapDownloadErrorCallback to be notified when an error occurred during the map download, whether it's the original download or an update
OnMapDownloadErrorCallback to be notified when an error occurred during the map download, whether it's the original download or an updateUsage :
Core.getInstance().addOnMapDownloadErrorObserver(this)
override fun onMapDownloadError(error: Error) {
//called if something happened during the map download (connection error, no space available, unzipping, etc)
val messageId = error.messageId // the message id of the error
val errorExplanation = error.detailedMessage // a more detailed message about the error (not always available, in this case an empty String is returned)
}The OnOfflinePeriodExpiredCallback to be notified when the offline period has expired
OnOfflinePeriodExpiredCallback to be notified when the offline period has expiredThe Core needs to be initialized with an online connection at first. Then, during a determined "offline period", the Core can be initialized without any internet connection. When this offline period is expired, this callback onOfflinePeriodExpired is called. It means that the Core can't be initialized without an internet connection : it needs an internet connection to validate your license in the BeNomad licensing system. After the Core is initialized with an internet connection again, the offline period is reset : you can initialize the Core without an internet connection.
Usage :
Core.getInstance().addOnOfflinePeriodExpiredObserver(this)
override fun onOfflinePeriodExpired() {
//this is triggered when the offline period has expired
//you have to initialize the Core with an active internet connection, otherwise the Core won't be initialized anymore
}