[Huawei Developers] HMS Community:
Introduction​

In this series of article, we will learn about Navigation Glove application and also we will learn about integration of the Huawei Direction API in Navigation Glove IoT application. We will learn how to draw polyline on the map.

If you are new to this series of articles, follow my previous articles.

Beginner: Integration of Huawei Account kit in Navigation Glove IoT application Using Kotlin - Part 1

Beginner: Integration of Huawei Map kit in Navigation Glove IoT application Using Kotlin - Part 2

Beginner: Integration of Huawei Site kit in Navigation Glove IoT application Using Kotlin - Part 3

What is Direction API?

Huawei Map Kit provides a set of HTTP/HTTPS APIs, which you can use to build map data functions like route planning, Static map, Raster map.

Directions API is a set of HTTPS-based APIs it is used to plans routes. The direction API returns data in JSON format. You can parse and draw route on the map.

It has following types of routes:

Walking: You can plan route max 150 kilometers.

Cycling: You can plan route max 100 kilometers.

Driving: Driving route gives some following functions:

1. It returns 3 routes for request.

2. It supports 5 waypoints.

3. It gives real time traffic condition.

Using Rest services we are integrating the following.

Direction API

Prerequisite​

AppGallery Account

Android Studio 3.X

SDK Platform 19 or later

Gradle 4.6 or later

HMS Core (APK) 4.0.0.300 or later

Huawei Phone EMUI 3.0 or later

Non-Huawei Phone Android 4.4 or later

Service integration on AppGallery.

1. We need to register as a developer account in AppGallery Connect.

2. Create an app by referring to Creating a Project and Creating an App in the Project.

3. Set the data storage location based on the current location.

4. Enabling Map Kit Service on AppGallery Connect.

5. Generating a Signing Certificate Fingerprint.

6. Configuring the Signing Certificate Fingerprint.

7. Get your agconnect-services.json file to the app root directory.

Client development

1. Create android project in android studio IDE.

2. Add the maven URL inside the repositories of buildscript and allprojects respectively (project level build.gradle file).

maven { url 'https://developer.huawei.com/repo/' }

3. Add the classpath inside the dependency section of the project level build.gradle file.

classpath 'com.huawei.agconnect:agcp:1.5.2.300'

4. Add the plugin in the app-level build.gradle file.

apply plugin: 'com.huawei.agconnect'

5. Add the below library in the app-level build.gradle file dependencies section.

implementation 'com.huawei.hms:maps:4.0.0.302'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'

6. Add all the below permissions in the AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

7. Sync the project.

By now user has select the Source location and Destination Location. And also we have added marker on the map.

Direction API Code

For direction API, we are using retrofit library to get the direction API.

So first let’s see what will be the Request and what will be response. And also end point.

Method Type: POST

URL:

https://mapapi.cloud.huawei.com/mapApi/v1/routeService/driving?key=

API key

Note: Replace API key with you project API key

Data Format: Request: Content-Type: application/json

Response: Content-Type: application/json

Request Example

POST https://mapapi.cloud.huawei.com/mapApi/v1/routeService/driving?key=API key HTTP/1.1

Content-Type: application/json

Accept: application/json

{
"destination":{
"lat":12.982126,
"lng":77.533103
},
"origin":{
"lat":12.9702763,
"lng":77.5373127
}
}

Response

HTTP/1.1 200 OK

Content-type: application/json

Just check it in the Postman or RestClient or any other tools which give response for HTTP request

Now let us set up

Step 1: Create Const class.

package com.huawei.navigationglove.api

object Const {

const val BASE_URL = "https://mapapi.cloud.huawei.com/mapApi/v1/"

}Copy codeCopy code

Step 2: Create ApiClient class.

package com.huawei.navigationglove.api

import android.content.Context
import android.text.TextUtils

import okhttp3.Interceptor

import okhttp3.logging.HttpLoggingInterceptor

import okhttp3.OkHttpClient

import retrofit2.converter.gson.GsonConverterFactory

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import okhttp3.HttpUrl
import okhttp3.Request

import retrofit2.Retrofit
import java.util.concurrent.TimeUnit

object ApiClient {
private val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(Const.BASE_URL)
.client(setInterceptors())
.addConverterFactory(GsonConverterFactory.create())
.build()

private fun setInterceptors(): OkHttpClient {
val logger = HttpLoggingInterceptor()
logger.level = HttpLoggingInterceptor.Level.BODY

return OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.addInterceptor { chain ->
val url: HttpUrl = chain.request().url.newBuilder()
.addQueryParameter(
"key",
"ADD_YOUR_API_KEY_HERE"
)
.build()
val request = chain.request().newBuilder()
.header("Content-Type", "application/json")
.url(url)
.build()
chain.proceed(request)
}
.addInterceptor(logger)
.build()
}

fun createApiService(): ApiService {
return ApiClient.retrofit.create(ApiService::class.java)
}

fun <S> createService(serviceClass: Class<S>?): S {
return retrofit.create(serviceClass)
}
}

Step 3: Create the ApiService interface.

package com.huawei.navigationglove.api

import com.huawei.navigationglove.api.request.DirectionRequest
import com.huawei.navigationglove.api.response.DirectionResponse
import io.reactivex.Single
import retrofit2.Call
import retrofit2.http.*

interface ApiService {
@POST("routeService/{type}")
fun getDirectionsWithType(
@Path(value = "type",encoded = true) type : String,
@Body directionRequest: DirectionRequest
): Call<DirectionResponse>
}Copy codeCopy code
Step 4: Create TypeOfDirection Enum to get routes for driving/walking/cycling

package com.huawei.navigationglove.api
enum class TypeOfDirection(val type: String) {
WALKING("walking"),
BICYCLING("bicycling"),
DRIVING("driving")
}

Before creating request and response class, let us add one plugin to convert from JSON to Kotlin data classes

Choose File > Setting > Plugin

Step 5: Now we need to create Request kotlin classes.

Origin.kt

package com.huawei.navigationglove.api.request

import com.google.gson.annotations.SerializedName

data class Origin(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

Destination.kt

package com.huawei.navigationglove.api.request

import com.google.gson.annotations.SerializedName

data class Destination(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

DirectionRequest.kt

package com.huawei.navigationglove.api.request

import com.google.gson.annotations.SerializedName

data class DirectionRequest(@SerializedName("origin")
val origin: Origin,
@SerializedName("destination")
val destination: Destination)

Step 6: Now create Response Class. Same as the Request class created.

DirectionResponse.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class DirectionResponse(@SerializedName("routes")
val routes: List<RoutesItem>?,
@SerializedName("returnCode")
val returnCode: String = "",
@SerializedName("returnDesc")
val returnDesc: String = "")

Bounds.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class Bounds(@SerializedName("southwest")
val southwest: Southwest,
@SerializedName("northeast")
val northeast: Northeast)

EndLocation.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class EndLocation(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

Northeast.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class Northeast(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

PathItems.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class PathsItem(@SerializedName("duration")
val duration: Double = 0.0,
@SerializedName("durationText")
val durationText: String = "",
@SerializedName("durationInTrafficText")
val durationInTrafficText: String = "",
@SerializedName("durationInTraffic")
val durationInTraffic: Double = 0.0,
@SerializedName("distance")
val distance: Double = 0.0,
@SerializedName("startLocation")
val startLocation: StartLocation,
@SerializedName("startAddress")
val startAddress: String = "",
@SerializedName("distanceText")
val distanceText: String = "",
@SerializedName("steps")
val steps: List<StepsItem>?,
@SerializedName("endLocation")
val endLocation: EndLocation,
@SerializedName("endAddress")
val endAddress: String = "")

PolylineItems.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class PolylineItem(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

RoutesItem.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class RoutesItem(@SerializedName("trafficLightNum")
val trafficLightNum: Int = 0,
@SerializedName("dstInDiffTimeZone")
val dstInDiffTimeZone: Int = 0,
@SerializedName("crossCountry")
val crossCountry: Int = 0,
@SerializedName("hasRestrictedRoad")
val hasRestrictedRoad: Int = 0,
@SerializedName("hasRoughRoad")
val hasRoughRoad: Int = 0,
@SerializedName("hasTrafficLight")
val hasTrafficLight: Int = 0,
@SerializedName("crossMultiCountries")
val crossMultiCountries: Int = 0,
@SerializedName("dstInRestrictedArea")
val dstInRestrictedArea: Int = 0,
@SerializedName("overviewPolyline")
val overviewPolyline: String = "",
@SerializedName("paths")
val paths: List<PathsItem>?,
@SerializedName("bounds")
val bounds: Bounds,
@SerializedName("hasTolls")
val hasTolls: Int = 0,
@SerializedName("hasFerry")
val hasFerry: Int = 0)

Southwest.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class Southwest(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

StartLocation.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class StartLocation(@SerializedName("lng")
val lng: Double = 0.0,
@SerializedName("lat")
val lat: Double = 0.0)

StepsItem.kt

package com.huawei.navigationglove.api.response

import com.google.gson.annotations.SerializedName

data class StepsItem(@SerializedName("duration")
val duration: Double = 0.0,
@SerializedName("orientation")
val orientation: Int = 0,
@SerializedName("durationText")
val durationText: String = "",
@SerializedName("distance")
val distance: Double = 0.0,
@SerializedName("startLocation")
val startLocation: StartLocation,
@SerializedName("instruction")
val instruction: String = "",
@SerializedName("action")
val action: String = "",
@SerializedName("distanceText")
val distanceText: String = "",
@SerializedName("roadName")
val roadName: String = "",
@SerializedName("endLocation")
val endLocation: EndLocation,
@SerializedName("polyline")
val polyline: List<PolylineItem>?)=

Now everything set now call the API.

If your question about originReq and destinationReq follow my previous article. These two request has been created when user selects the source location and destination location.

navigate.setOnClickListener {
val directionRequest = DirectionRequest(originReq!!, destinationReq!!)
getDirection(directionType, directionRequest)
}Copy codeCopy code

private fun getDirection(directionType: String, directionRequest: DirectionRequest) {
ApiClient.createApiService()
.getDirectionsWithType(directionType, directionRequest)
.enqueue(object : Callback<DirectionResponse> {
override fun onFailure(call: Call<DirectionResponse>, t: Throwable) {
Toast.makeText(
this@HomeScreenActivity,
"Failure" + t.localizedMessage + "\n" + t.message,
Toast.LENGTH_SHORT
).show()
}

override fun onResponse(
call: Call<DirectionResponse>,
response: Response<DirectionResponse>
) {
if (response.isSuccessful) {
response.body()?.let {
it.routes?.get(0)?.paths?.get(0)?.let { it1 -> addPolyLines(it1) }
Toast.makeText(this@HomeScreenActivity, "Success", Toast.LENGTH_SHORT)
.show()
}
//startActivity(Intent(this@HomeScreenActivity, MapsActivity::class.java))
}
}

})
}

Adding polyline

var polyLine: Polyline? = null
private fun addPolyLines(path: PathsItem) {
if (polyLine != null) {
polyLine!!.remove()
}
val options = PolylineOptions()
options.add(LatLng(path.startLocation.lat, path.startLocation.lng))
path.steps!!.forEach {
it.polyline!!.forEach { it1 ->
options.add(LatLng(it1.lat, it1.lng))
}
}
options.add(LatLng(path.endLocation.lat, path.endLocation.lng))
options.color(Color.BLACK)
options.width(6f)
polyLine = hMap!!.addPolyline(options)

}

Now let us see the full code.

HomeScreenActivity.kt

package com.huawei.navigationglove.ui

import android.content.Intent
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import com.huawei.hms.maps.*
import com.huawei.hms.maps.model.*
import com.huawei.hms.site.api.model.Site
import com.huawei.hms.site.widget.SearchIntent

import com.huawei.navigationglove.R
import com.huawei.navigationglove.api.ApiClient
import com.huawei.navigationglove.api.TypeOfDirection
import com.huawei.navigationglove.api.request.Destination
import com.huawei.navigationglove.api.request.DirectionRequest
import com.huawei.navigationglove.api.request.Origin
import com.huawei.navigationglove.api.response.DirectionResponse
import com.huawei.navigationglove.api.response.PathsItem

import kotlinx.android.synthetic.main.activity_home_screen.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.net.URLEncoder
import android.widget.RadioButton

class HomeScreenActivity : AppCompatActivity(), OnMapReadyCallback {
private val TAG = HomeScreenActivity::class.java.name
private val API_KEY: String =
"Add your API Key here"
private var originReq: Origin? = null
private var destinationReq: Destination? = null
var hMap: HuaweiMap? = null
private val searchIntent = SearchIntent()
private var mMarker: Marker? = null
private var mCircle: Circle? = null
private var directionType: String = TypeOfDirection.WALKING.type
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_screen)
val mSupportMapFragment: SupportMapFragment? =
supportFragmentManager.findFragmentById(R.id.mapfragment_mapfragmentdemo) as SupportMapFragment?
mSupportMapFragment!!.getMapAsync(this)

//Site kit
val apiKey = URLEncoder.encode(
API_KEY,
"utf-8"
)
searchIntent.setApiKey(apiKey)

//Select source location
start.setOnClickListener {
//You can try the below one for older method
//selectSourceLocation()
/*val intent = searchIntent.getIntent(this)
startActivityForResult(intent, SearchIntent.SEARCH_REQUEST_CODE)*/
selectSourceLocation()
}

//Select Destination Location
destination.setOnClickListener {
selectDestinationLocation()
}

navigate.setOnClickListener {
val directionRequest = DirectionRequest(originReq!!, destinationReq!!)
getDirection(directionType, directionRequest)
}

directionTypeGroup.setOnCheckedChangeListener { group, checkedId -> // checkedId is the RadioButton selected
val directionTypeRadioButton = findViewById<View>(checkedId) as RadioButton
when (directionTypeRadioButton.text.toString().toLowerCase()) {
"walking" -> directionType = TypeOfDirection.WALKING.type
"driving" -> directionType = TypeOfDirection.DRIVING.type
"cycling" -> directionType = TypeOfDirection.BICYCLING.type
}
Toast.makeText(applicationContext, directionTypeRadioButton.text, Toast.LENGTH_SHORT)
.show()
}
}

private fun selectSourceLocation() {
val intent = searchIntent.getIntent(this)
sourceLocationLauncher.launch(intent)
}

private var sourceLocationLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data: Intent? = result.data
if (data != null) {
if (SearchIntent.isSuccess(result.resultCode)) {
val site: Site = searchIntent.getSiteFromIntent(data)
start.text = site.getName()
originReq = Origin(site.location.lng, site.location.lat)
//originReq = Origin(-4.66529, 54.216608)
//Toast.makeText(application, site.getName(), Toast.LENGTH_LONG).show()
val build = CameraPosition.Builder()
.target(LatLng(site.location.lat, site.location.lng)).zoom(16f).build()
val cameraUpdate = CameraUpdateFactory.newCameraPosition(build)
hMap!!.animateCamera(cameraUpdate)
//Setting max and min zoom
//hMap!!.setMaxZoomPreference(10f)
//hMap!!.setMinZoomPreference(1f)
// Marker can be add by HuaweiMap
mMarker = hMap!!.addMarker(
MarkerOptions().position(LatLng(site.location.lat, site.location.lng))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_baseline_location_on_24))
.clusterable(true)
)
mMarker?.showInfoWindow()

// circle can be added to HuaweiMap
/*mCircle = hMap!!.addCircle(
CircleOptions().center(LatLng(28.7041, 77.1025)).radius(45000.0).fillColor(
Color.GREEN))
mCircle?.fillColor = Color.TRANSPARENT*/

}
} else {
Toast.makeText(application, "Unable to find the data", Toast.LENGTH_LONG).show()
}
}

private fun selectDestinationLocation() {
val intent = searchIntent.getIntent(this)
destinationLocationLauncher.launch(intent)
}

private var destinationLocationLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data: Intent? = result.data
if (data != null) {
if (SearchIntent.isSuccess(result.resultCode)) {
val site: Site = searchIntent.getSiteFromIntent(data)
destination.text = site.getName()
destinationReq = Destination(site.location.lng, site.location.lat)
//destinationReq = Destination(-4.66552, 54.2166)
val build = CameraPosition.Builder()
.target(LatLng(site.location.lat, site.location.lng)).zoom(16f).build()
val cameraUpdate = CameraUpdateFactory.newCameraPosition(build)

hMap!!.animateCamera(cameraUpdate)
mMarker = hMap!!.addMarker(
MarkerOptions().position(LatLng(site.location.lat, site.location.lng))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_baseline_destination_location_on_24))
.clusterable(true)
)
mMarker?.showInfoWindow()

}
} else {
Toast.makeText(application, "Unable to find the data", Toast.LENGTH_LONG).show()
}
}

override fun onMapReady(huaweiMap: HuaweiMap) {
Log.d(TAG, "onMapReady: ")
hMap = huaweiMap
hMap!!.mapType = HuaweiMap.MAP_TYPE_NORMAL
hMap!!.uiSettings.isMyLocationButtonEnabled = true

// Add a polyline (mPolyline) to a map.
/* val mPolyline = hMap!!.addPolyline(
PolylineOptions().add(
LatLng(47.893478, 2.334595),
LatLng(48.993478, 3.434595),
LatLng(48.693478, 2.134595),
LatLng(48.793478, 2.334595)
)
)
// Set the color of the polyline (mPolyline) to red.
mPolyline.color = Color.RED
// Set the width of the polyline (mPolyline) to 10 pixels.
mPolyline.width = 10f*/

//Adding Polygon
/*hMap!!.addPolygon(PolygonOptions().addAll(createRectangle(LatLng(12.9716, 77.5946), 0.1, 0.1))
.fillColor(Color.GREEN)
.strokeColor(Color.BLACK))*/

//Adding Circle on the Map
/*hMap!!.addCircle(CircleOptions()
.center(LatLng(12.9716, 77.5946))
.radius(500.0)
.fillColor(Color.GREEN))*/

}

private fun createRectangle(
center: LatLng,
halfWidth: Double,
halfHeight: Double
): List<LatLng> {
return listOf(
LatLng(center.latitude - halfHeight, center.longitude - halfWidth),
LatLng(center.latitude - halfHeight, center.longitude + halfWidth),
LatLng(center.latitude + halfHeight, center.longitude + halfWidth),
LatLng(center.latitude + halfHeight, center.longitude - halfWidth)
)
}

private fun getDirection(directionType: String, directionRequest: DirectionRequest) {
ApiClient.createApiService()
.getDirectionsWithType(directionType, directionRequest)
.enqueue(object : Callback<DirectionResponse> {
override fun onFailure(call: Call<DirectionResponse>, t: Throwable) {
Toast.makeText(
this@HomeScreenActivity,
"Failure" + t.localizedMessage + "\n" + t.message,
Toast.LENGTH_SHORT
).show()
}

override fun onResponse(
call: Call<DirectionResponse>,
response: Response<DirectionResponse>
) {
if (response.isSuccessful) {
response.body()?.let {
it.routes?.get(0)?.paths?.get(0)?.let { it1 -> addPolyLines(it1) }
Toast.makeText(this@HomeScreenActivity, "Success", Toast.LENGTH_SHORT)
.show()
}
//startActivity(Intent(this@HomeScreenActivity, MapsActivity::class.java))
}
}

})
}

var polyLine: Polyline? = null
private fun addPolyLines(path: PathsItem) {
if (polyLine != null) {
polyLine!!.remove()
}
val options = PolylineOptions()
options.add(LatLng(path.startLocation.lat, path.startLocation.lng))
path.steps!!.forEach {
it.polyline!!.forEach { it1 ->
options.add(LatLng(it1.lat, it1.lng))
}
}
options.add(LatLng(path.endLocation.lat, path.endLocation.lng))
options.color(Color.BLACK)
options.width(6f)
polyLine = hMap!!.addPolyline(options)

}
}

activity_home_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.HomeScreenActivity">

<fragment
android:id="@+id/mapfragment_mapfragmentdemo"
class="com.huawei.hms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="12.9716"
map:cameraTargetLng="77.5946"
map:cameraZoom="10" />

<androidx.cardview.widget.CardView
android:id="@+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:elevation="100dp"
app:cardBackgroundColor="@android:color/white"
app:cardCornerRadius="8dp">

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<LinearLayout
android:id="@+id/locationLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="9.5"
android:background="@color/white"
android:orientation="vertical"
android:padding="20dp">

<TextView
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:background="@android:color/transparent"
android:hint="Choose a starting point..."
android:maxLines="1"
android:textColor="@color/purple_200"
android:textSize="18sp" />

<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="5dp"
android:background="@drawable/dottet_line" />

<TextView
android:id="@+id/destination"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:hint="Choose a destination..."
android:maxLines="1"
android:textSize="18sp"
android:textColor="@color/purple_200"/>
</LinearLayout>

<ImageView
android:id="@+id/navigate"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_gravity="center"
android:layout_marginRight="10dp"
android:layout_weight="0.5"
android:src="@drawable/ic_baseline_send_24" />

</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@drawable/dottet_line" />

<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:id="@+id/directionTypeGroup"
android:orientation="horizontal">

<RadioButton
android:id="@+id/walking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:checked="true"
android:text="Walking" />

<RadioButton
android:id="@+id/driving"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:text="Driving" />

<RadioButton
android:id="@+id/cycling"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:text="Cycling" />
</RadioGroup>

</LinearLayout>
</androidx.cardview.widget.CardView>

</FrameLayout>

Result​

Tips and Tricks​

1. Make sure you are already registered as a Huawei developer.

2. Set min SDK version to 21 or later, otherwise you will get AndriodManifest to merge issue.

3. Make sure you have added the agconnect-services.json file to the app folder.

4. Make sure you have added the SHA-256 fingerprint without fail.

5. Make sure all the dependencies are added properly.

6. If you want location feature in the Map, make sure you add location permission in AndroidManifest.xml file.

7. If you install app in android version 6 or greater than make sure you handled run time permission.

8. Make sure you have encoded your API key with URLEncode UTF-8.

Conclusion​

In this article, we have learnt the integration of the Direction API in Navigation Glove application using Android Studio and Kotlin. And also we have learnt how to convert the JSON to kotlin data classes. And also we have learnt the integration of the retrofit in the application.

Reference​

Map Kit - Official document

Map Kit - Code lab

Map Kit - Training Video

Map Kit - Direction API