Skip to content

Android

Introduction

This tutorial will walk you through the step-by-step process of integrating the Telenav SDK (TASDK) into your Android application. TASDK is a comprehensive solution designed to provide all the essential navigation features you need, including advanced routing algorithms, real-time guidance, precise positioning, ADAS (Advanced Driver Assistance Systems) integration, voice assistance, high-performance map rendering, and customizable UI components. By following this tutorial, you will gain a clear understanding of how to set up and utilize TASDK, enabling you to implement a fully functional basic navigation feature in your application by the end of the guide.

Prerequisites:

  • Basic knowledge of Android development using Kotlin or Java.
  • Android Studio installed.
  • An API key and API secret for the TASDK.

System Requirements

  • Android device with ARM or x86_64 architecture.
  • Android 6.0 (API 23) or above.
  • Java 8 or higher.
  • Kotlin 1.6.10 or higher.
  • NDK versions r15c or r19c supported.

Add the following to the android block in your build.gradle file to ensure compatibility:

1
2
3
4
5
6
7
compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
  jvmTarget = '1.8'
}

Get Started

Step 1: Set Up Your Project

1. Add TASDK Dependency

Open your Android Studio project and add the following dependencies to your project's build.gradle file:

repositories {
  ...
  // aliyun maven repo
  maven {
    url 'https://maven.aliyun.com/repository/public'
  }
  maven {
    credentials {
        username '###'
      password '###'
    }
    url 'https://packages.aliyun.com/maven/###'
 }

}

dependencies {
    // LTS2
    implementation("com.telenav.sdk:telenav-android-drivesession:${tasdk_version}")
    implementation("com.telenav.sdk:telenav-android-mapview:${tasdk_version}")
    // or LTS4
    implementation("com.telenav.sdk:telenav-android-drivesession-rc15:${tasdk_version}")
    implementation("com.telenav.sdk:telenav-android-mapview-rc15:${tasdk_version}")
    implementation("com.telenav.sdk:telenav-android-ngx-r15c:${mapplugin_version}")
}

Sync your project by clicking Sync Now.

2. Add Required Permissions:

Add the following permissions for location access in your AndroidManifest.xml:

1
2
3
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

Step 2: Initialize TASDK

1. Configure SDK Options:

ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permission required.

val options = SDKOptions.builder()
  .setApiKey("#YOUR_API_KEY") // Must have
  .setApiSecret("#YOUR_API_SECRET")// Must have
  .setCloudEndPoint("#END_POINT")// Must have
  .setSdkDataDir("#ONBOARD_MAP_DATA_PATH")// Hybrid mode
  .setLocale(Locale.EN_US)
  .setUserId("#USER_ID")
  .build();
val navSDKOptions = NavSDKOptions.builder(options)
  .setTrafficExpireTime(60)// Default value is 120
  .setTrafficRefreshTime(60)// Default value is 120
  .enableSelfPropellingUponWeakGPS(true)
  .enablePositionEngineLog(true)
  .enableADASLog(true)
  .enableHDMap(true)
  .setMapStreamingSpaceLimit(1024 * 1024 * 1024L)// 1GB is recommended
  .setArrivalDistanceThreshold("#LOCAL_DISTANCE_THRESHOLD","#HIGHWAY_DISTANCE_THRESHOLD")
  .setBatteryConsumedCheckPercent(10) // EV feature,Default value is 5%
  .setChargingStationStatusCheckRemainingTime(300)// EV feature
  .setRegion("NA")
  .build();                
val result = SDK.getInstance().initialize(context, navSDKOptions);
2. Set Up MapView:

Declare Mapview on the target layout.

<androidx.constraintlayout.widget.ConstraintLayout                   
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

  <com.telenav.map.views.TnMapView
    android:id="@+id/map_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. Initialize MapView:
public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {
  super.onViewCreated(view, savedInstanceState);
  val mapViewConfig = MapViewInitConfig(
            context = this.applicationContext,
            lifecycleOwner = this,
            dpi = map_view.defaultDpi,
            defaultLocation = Location("").apply {
                this.latitude = 37.3982607
                this.longitude = -121.9782241
            },
            readyListener = readyListener,
            createCvp = false,
            autoZoomLevel = AutoZoomLevel.FAR
        )
    map_view.initialize(mapViewConfig)
}

Build and Run your application on Device.Now you should be able to see the map, it will use the default map styles the SDK is shipped with. pan/zoom operations are supported. Also, there are other subset APIs exposed, including: setZoomLevel and followVehicle.

Step 3: Get Direction

1. Initialize a direction client.
//Depends on the use case, you can hold directionClient on your fragment or activity or //applicaiton
val directionClient = DirectionClient.Factory.hybridClient();
2. Create a routing request
1
2
3
4
5
6
7
val request = RouteRequest.Builder(
            GeoLocation(37.405022, -122.061887),
            GeoLocation(37.39962, -121.977785)
        )
            .contentLevel(ContentLevel.FULL)
            .routeCount(2)
            .build()
3. Create a request task and execute
1
2
3
4
5
6
7
8
9
task.runSync { response: RouteResponse ->
            if (response.getResponse().status == DirectionErrorCode.OK) {
                Log.i("Direction", "route requesting success! routes: " + response.response.result)
                val route: Route = response.response.result[0]
            } else {
                Log.e("Direction", "route requesting failed");
            }
            task.dispose()
        }

Step 4: Work with DriveSession

Drive session is the most important component of our SDK. It serves map-matching, navigation, alerts and other important services.

As with our other service components, the user creates the drive session instances via a factory.

val driveSession = DriveSession.Factory.createInstance()

By default, some of its services like the position service will automatically run once the drive session instance been created. If you don't want some services, you can disable them when drive session initialize.

val driveSession = DriveSession.Factory.createInstance(DriveSessionOption.Builder().disableAdas().disableAudioGuidance().disableAlert().build())

There is another important concept named event hub which using for communicating between each service and the SDK user during runtime, SDK user can get the event hub instance with getEventHub function call:

val eventHub = driveSession.eventHub
// TODO, add or remove spesific service listener
//  ...
driveSession.eventHub.addPositionEventListener(object : PositionEventListener {

    override fun onLocationUpdated(vehicleLocation: Location, positionInfo: PositionInfo) {
        // TODO: the output parameter is map-matched location   
    }

    override fun onCandidateRoadDetected(roadCalibrator: RoadCalibrator) {
    // TODO: present street information current driving along with
    }
})
Start navigation

start a new navigation session with startNavigation function call

val navigationSession = driveSession.startNavigation(route, false, 40.0)

During an active navigation session, the SDK will broadcast navigation signals (at 1Hz frequenct) informing each other on the status of current navigation session, following information included:

  • distance to turn
  • turn type(icon) of current step
  • next street name
  • highway EXIT label and other signpost strings(if availible)
  • lane patterns(if available)
  • junction view image(if available)
  • ETA of upcoming stop or destination

After completing the above four steps, you have successfully integrated the TASDK into your Android app. You can now expand its capabilities to provide a full navigation experience.

Enable HDMap

Environment variable setup

In order to receive notifying message from SD navigation SDK correctly, the user needs to specify an port of the machine running SD navigation SDK by HDMap service options.

Os.setenv(Constants.KEY_TASDK_BROKER_SERVER_PORT, "#port num", true);

For avoiding the conflict of ports when more than one client integrates HDMap SDK, SD navigation SDK has a strategy to automatically select a randomized address port of the broker if not set.

The user must not use the randomized port in range of [20000, 20099].

Customize the map UI

Replace default configurations for UI customization

There are different configurations for different oem projects.Client can replace default configurations with oem configurations.Oem configurations must be high priority that other tasdk packages.

1
2
3
4
implementation(name:'telenav-android-configuration-oem', ext:'aar')
implementation ("com.telenav.sdk:telenav-android-mapview:${tasdk_version}") {
   exclude group: "com.telenav.sdk", module: "telenav-android-configuration"
}

Dispose

Lastly, make sure to clean up when the activity lifetime ends: TASDK for Android provides the methods as shown below - to safely release all of its remaining resources.

@Override
protected void onResume() {
    mapView.onResume();
    super.onResume();
}

@Override
protected void onPause() {
    mapView.onPause();
    super.onPause();
}

@Override
protected void onDestroy() {
    driveSession.eventHub.removePositionEventListener(this)
    driveSession.eventHub.removeNavigationEventListener(this)
    ...
    driveSession.dispose()
    SDK.getInstance().dispose()
    super.onDestroy();
}

Troubleshooting

If you encounter any issues, please first ensure that you have reviewed the System Requirements

  1. I see only blank black map in pure streaming mode: Make sure that API key/API secret and endpoint are valid or Region is set. Or check your network connectivity.
  2. Custom configs not work : Ensure the oem configurations package with higher priority than other tasdk package.In practices, the local package takes precedence over the remote package. Refer to the (https://developer.android.com/studio/build/dependencies) for detail.
  3. Get a crash due to onboard data can't access: Verify that the SDK data directory is correctly configured and accessible.