Quick Start
This guide makes the implementation of our SDK in your app as easy as possible.
Minimal requirements
- Android device running API 23 and above
- Since this is an offline maps-based SDK, sufficent space on internal or external storage is required
Adding the library to your project
Add this piece of code to settings.gradle
dependencyResolutionManagement {
..
repositories {
..
maven {
url "https://sdk.mapfactor.com/repo/release"
credentials {
username "$mavenUsername"
password "$mavenPassword"
}
}
}
}
or build.gradle
for older projects
allprojects {
repositories {
..
maven {
url "https://sdk.mapfactor.com/repo/release"
credentials {
username "$mavenUsername"
password "$mavenPassword"
}
}
}
}
Edit your gradle.properties
mavenUsername=askForUsername
mavenPassword=askForPassword
Configure your build.gradle
dependencies {
implementation "com.mapfactor:sdk:x.y.z"
}
Adding to the layout
Add implementation 'com.google.android.material:material:x.y.z'
for back compatibility. Use FragmentActivity instead of a ComponentActivity successor to support our Fragment.
Jetpack Compose
In case of using Jetpack Compose, check Inter-op with XML inter-op docs by Google.
Insertion to the layout can be executed either by view or fragment. Our MapView
is basically a view containing MapFragment
.
MapView element
View plays the role of a wrapper around our MapFragment
. Once MapView
is inflated, you can access the inner fragment.
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
MapView(context).apply {
//do whatever you want, e.g.
//set night mode
this.mapFragment.setNightMode(true)
//handle map controls visibility
val mapControls = this.mapFragment.mapControls
mapControls.setMapControlVisibility(
MapControls.MapControl.COMPASS,
true
)
//or add listener
this.mapFragment.addOnMapReadyListener {
}
}
},
update = {
}
)
Fragment element
You need to create an XML layout file in res/layout. e.g. fragment_navigation.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container_view"
android:name="com.mapfactor.sdk.map.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
and then use this layout to inflate in Kotlin like this.
AndroidViewBinding(FragmentNavigationBinding::inflate) {
val mapFragment = fragmentContainerView.getFragment<MapFragment>()
//do whatever you want, e.g.
//set night mode
mapFragment.setNightMode(true)
//handle map controls visibility
val mapControls = mapFragment.mapControls
mapControls.setMapControlVisibility(
MapControls.MapControl.COMPASS,
true
)
//or add listener
mapFragment.addOnMapReadyListener {
}
}
For more information, check official Google documentation.
View-based system
For layout implementation, there are two options - direct XML view containing MapFragment
on background or inserting a MapFragment
with FragmentContainerView.
MapView element
<com.mapfactor.sdk.map.MapView
android:id="@+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Fragment element
<androidx.fragment.app.FragmentContainerView
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.mapfactor.sdk.map.MapFragment"/>
Initialization
To ensure our SDK works properly, add dependencies to a build.gradle
:
implementation "androidx.compose.ui:ui-viewbinding:x.y.z"
implementation "androidx.fragment:fragment-ktx:x.y.z"
implementation 'androidx.constraintlayout:constraintlayout:x.y.z'
buildFeatures {
viewBinding true
}
You will need to add permissions to access device location to AndroidManifest.xml
as follows.
<manifest..>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<manifest>
The key to run our SDK is MpfcEngine’s initโ
method.
// get path
val sdkDataPath = getExternalFilesDir(null).toString()
// get renderer
val rendererName: RendererName = RendererName.HARDWARE
// get map data provider
val mapDataProvider: ProviderName = ProviderName.OSM
//get language
val lang = "en"
MpfcEngine.getInstance().init(this, sdkDataPath, mapDataProvider, rendererName, lang, object :
MpfcEngine.InitListener {
override fun onLocationPermissionNotGranted() {
// notify an activity to make a request for location permission,
// e.g. using broadcast intent
}
override fun onEngineInitStatusChanged(initStatus: MpfcEngine.InitStatus) {
// log
}
override fun onEngineInitFinished(initStatusResult: MpfcEngine.InitResult) {
if (result == MpfcEngine.InitResult.SUCCESS) {
//HURAYYY, do whatever you want, e.g.
initActiveVehicle()
getAllAvailableVehicles()
setCurrentLanguage()
} else if (result == MpfcEngine.InitResult.FAILED_DEVICE_NOT_ACTIVATED
|| result == MpfcEngine.InitResult.FAILED_SDK_NOT_LICENSED) {
//oops, activate device
activateDevice()
}
}
})
fun activateDevice() {
MpfcEngine.getInstance().activateDevice(
getApplication(),
"AAAAA-BBBBB-CCCCC-DDDDD-EEEEE"
) { activationResult: MpfcEngine.ActivationResult ->
val succeeded =
activationResult == MpfcEngine.ActivationResult.SUCCEEDED ||
activationResult == MpfcEngine.ActivationResult.ALREADY_ACTIVATED
...
}
}
From now on theMpfcEngine
instance is used for most use cases.
Data download
For downloading map, voice and sound data, use the downloadAppData
method of the AppDataManagerModule
.
MpfcEngine.getInstance().appDataManagerModule
.downloadAppData(dataIds, object : DataDownloadListener {
override fun onDownloadProgress(
dataId: String,
dataName: String,
iFile: Int,
numFiles: Int,
curFileProgress: Long,
curFileSize: Long,
totProgress: Long,
totSize: Long
) {
//process current progress
}
override fun onDownloadFinished() {
}
override fun onDownloadFailed(errorCode: AppDataManager.DownloadErrorCode) {
//handle error
}
override fun onEngineRestarted() {
}
})
callbackFlow
.onEngineRestarted
callback is invoked.