Introduction to the Geotab Java SDK for Go Devices with Kotlin and Ktor

Chris Basinger
Apr 29 · 4 min read

For the most part, this article will be about getting a list of your vehicles and their associated location history using Geotab’s Java SDK. From there, the data will be served up in JSON format in a REST API using Ktor and Kotlin.

The most important thing to do first is to create your GeotabApi object. You will use this to make calls to your Geotab database. You do this by first creating your Credentials object which is what you’ll pass in as the parameter for instantiating your GeotabApi object. After this, of course, you’ll need to authenticate with it.

Instantiate your GeotabApi object

Let’s go ahead and stash a global property with a getter method to avoid re-authenticating to the server every time we need the login result credentials.

Now, the next step is to get your Go Devices so you can then use their ids to get further information out of the databases. But for now, let’s get the information from the Go Device database table. I’m going to start by creating a KTX function with a receiver of type GeotabApi using that object we created in the last step.

Request a list of your Go Devices

The next step is to get the vehicle location history out of the database. The way we find this information is with the Go device’s id. So, once we’ve got a reference to the list of Go devices we can then select one and use its’ associated id to query your database for a list of location history for it. It allows for two parameters to create a date range. We can call these from and to for the range. It also allows for a result limit. However, be aware that it is sorted in ascending order by the date/time.

The function I’ve written wraps this API call to allow you to leave out the date range which then will default to all of the records. I’m putting up a REST API for another company to consume the data. Therefore, I chose to allow them to perform GET requests to the API allowing them to pass in parameters with millisecond epoch time stamps. I’m currently having occasional bugs with this function. However, it works intermittently.

Get the location history for a Go Device using its id.

In the previous code snippet, I went ahead and mapped the data to only the information relating to the location coordinates. Here is the snippet for that.

PODO for trimming down a LogRecord to extract just the location data

We’ve managed to extend the preexisting Geotab API with new functionality to match our requirements. Now, let’s wire these functions up with a service. Granted, here should be passing in a repository as well. However, for now we will be only utilizing a service.

Let’s import Koin onto the stack and install the feature. First add the Koin version to your gradle.properties file.

Next, go ahead and add its’ dependencies and plugin to your buildscript dependencies, plugins, and app dependencies sections of your build.gradle file.

Let’s go ahead and create a dependency container for Koin inside of a module. Here, we’re going to inject the GeotabApi into our GeotabService. This is where you pass in your Geotab credentials along with the name of your database which can be found at the top of your admin console upon logging in.

The last step with Koin is to inject the application’s dependencies onto the heap in the Application.kt file or whatever you’ve named your function that you run to start the application. Make sure to install Koin below any other features that you’ve installed. You’re going to pass the previously defined dependency module named appModule in as the argument to the Koin feature configuration block’s KTX function named modules. Later on, we’re going to pass this service that we’ve injected as the argument to our API routing function.

The next step is creating the API endpoints for the data using Ktor locations API.

The API hierarchy for the routes.

Next, we need to install the StatusPages feature for handling exceptions that are uncaught. Find your Application.kt file and install these feature within the Application.module function’s body. In my code, I will be throwing exceptions on purpose within the routes. I included several of my own implementations of an Exception. You’ll its definition right above the feature installation.

Finally, we need to go ahead and create our API’s endpoints. We do this by setting GET HTTP routes to our already defined paths that we configured using the Locations API. This is where we finally use our service. The service will be used to retrieve any data needed for the HTTP JSON responses.

register the HTTP routes under a Route KTX function

Alas, the final step of the process. We don’t need to actually install the routing feature into the app. Instead, Ktor provides you with a routing KTX function that we can use inside of the Application.module function. So, right below where you injected your service is where we will call this function to finish wiring up our REST API. Make sure you pass in the service as the argument to the apiRoutes function.

I was just kidding. Of course we’re not done yet! I knew you were disappointed thinking it was over. It's always important to test things so I’ve given you some test cases to run against the API. I use Kotest library. Granted, these test cases require your vehicle to have location history after New Year’s Day and before Valentine’s Day. You can change the values with your UNIX timestamps at the top of the file.

Thanks for reading and stay tuned for my next Geotab SDK tutorial.

Nerd For Tech

From Confusion to Clarification

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Chris Basinger

Written by

I create open-source Android libraries.

Nerd For Tech

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.