Developing environment
This project is written with Google’s official IDE “Android studio”, with a developing framework called “Jetpack-Compose”.
- Install IDE: https://developer.android.google.cn/codelabs/basic-android-kotlin-compose-install-android-studio
- Open the project: Click ‘open’ and open the folder “vibration_data_sensing”

- Build and run the app on an Android phone: https://developer.android.google.cn/studio/run/device
- Read the official starter documents for jetpack-compose framework.https://developer.android.google.cn/courses/android-basics-compose/course You don’t need to read all of them, as long as you can understand the file “MainActicity.kt” - what are @Composable functions? Where is the UI defined? Which code runs when the app starts?
- For sake of time, I don’t recommend learning a new language “Kotlin” and all of its grammar from zero. Do the preparations below, and let ChatGPT do the rest for you. Here is a very helpful AI coding tool: Cursor
Preparations
To start modifying the vibration data collection app, you’ll need these basic knowledge.
- Basic knowledge of object oriented programming.
- The “declaration programming” concept in Jetpack-Compose developing framework.
- Basically, you’ll find many functions annotated “@Composable” in the code. Such functions describes a mechanism that the app would keep track of some variables. Whenever they changes, the app run some code written in the function and update the changes in the UI component.
- You don’t have to manually consider every detail of the state shifting. Android automatically monitor and decide when to update the UI. So it is called “declaration”.
- Learn that the MQTT protocol requires a router, a broker, and several client devices. Learn about the publish-subscribe relation between clients.
- Learn about multi-thread operations in mobile apps.
- Network operations must be put in back-stage threads.
- To make back-stage threads not mixed with each other (e.g. prevent sending get-gain commands to a sensor while another thread is sending get-rate commands to it), lock is used in the code.
Structure of the code
1. Three salient instances in the code
The app monitors and uses 3 salient instances - broker, devices, files. They are digital twins of devices in the real-world or data in the disk. Let’s look at the definition of their class first.
class Broker {
var reachable by mutableStateOf(false)
var name by mutableStateOf("Not found")
var ip by mutableStateOf("Not found")
var status by mutableStateOf("Please start a broker on port 1883!")
}
There will always be one broker instance in the app, describing the broker’s name, IP, status.