Published on: February 25, 2024

Build bicycle tracker using Kotlin (Part 1)

I love cycling, and I’m excited to share that I’m gearing up for the ultra cycling event from Berlin to Munich and back, happening in August 2024. I’ve already started training hard for it.

To keep everyone in the loop and ensure my safety during the race, I’m planning to create an app. This app will use my phone as a client to send my location to the server every 5-10 minutes while I’m cycling. Then, my friends and family can see where I am on a map through a website on their computers or phones.

The app will be super easy to use. It’ll just show a map with a dot indicating where I am at that moment. This way, my loved ones can cheer me on and know I’m safe throughout the event.

Decision on stack

I’ve chosen to develop server side using Ktor. Ktor is a framework designed for building both server-side and client-side applications with Kotlin, a modern programming language. It’s built on Kotlin coroutines, which are lightweight and efficient for handling concurrent tasks.

To display my location, I’ve opted for server-side templating with Freemarker. I’ve chosen this approach to keep things simple, avoiding the need to build a full-fledged web application using React, Angular, or Vue.js. Since the goal is to have just one page showing the location on a map, this streamlined approach seems fitting.

For the client side, I’m looking into using Compose Multiplatform, a modern UI framework written in Kotlin. This will allow me to create a seamless and responsive user interface across different platforms while leveraging the power and flexibility of Kotlin.

Setup the server side

To start the Ktor project go to Ktor project generator where you can configure all dependencies needed fo the project. Ktor is designed to be flexible and customizable. Depending on your needs, you can add various plugins to your project as Gradle dependencies. In this case I have decided to use folowing ktor dedendencies which are called

The project generated by the Ktor project generator comes with a basic project structure. I’ve opted to use Gradle as the build tool, configured with Kotlin. The generated project includes Gradle’s wrapper, so there’s no need to install Gradle separately on your machine. The only requirement is to have Java installed.

Files Application.kt and Routing.kt contains minimal code to run the application and to configure simple routing for get request. Exposing simple GET endpoint look like:

”`kotlin fun Application.configureRouting() {

routing {
    get("/") {
        call.respondText("Hello World!")
    }

}

} “`

Configure dependency injection

Dependency injection is a widely used pattern in the Java ecosystem, as well as in object-oriented languages in general. It promotes loose coupling by separating object construction from their usage. While the Spring framework is the go-to choice for dependency injection in Java and it can be used in Kotlin, for smaller applications, it might be overkill. That’s why I’ve opted to use Koin, a lightweight dependency injection framework written in Kotlin, which offers simplicity and efficiency for smaller projects.

Add depdency io.insert-koin:koin-ktor, Ktor plugin for Koin depdency injection inside Gradle build file build.gradle.kts. Add Koin.kt file to install Koin plugin.

”`kotlin fun Application.configureKoin() {

install(Koin) {

}

} “`

Running Ktor application

The project generated by the Ktor project generator comes pre-configured with Gradle tasks for building and running the Ktor application. You can view all available tasks by running the command:

bash ./gradlew tasks

To run the application via Gradle, execute the following Gradle task: bash ./gradlew runFatJar

To build fat jar, execute the following Gradle task:

bash ./gradlew buildFatJar
The executable jar is located under directory * build/libs/* with suffix all.

Conclusion

I’ve outlined the initial steps to bootstrap a Ktor application in this post, which shouldn’t take more than 15 minutes to set up. You can see all code on my github account. Changes described in this post you can see here.

Given my professional background mostly in backend development, this part is relatively straightforward for me. However, the real challenge lies in building the mobile client using the Compose Multiplatform framework. But hey, challenges are what keep life exciting, right? And speaking of excitement, let’s not forget about keeping track of my cycling training progress – that’s a whole other journey on its own! Stay tuned for my next post!