Safe Driving Score Calculator using Vehicle SDK
Overview & Goals
This online tutorial is designed for developers who are new to vehicle app development but have experience in Android app (mobile or tablet) development and a basic understanding of Android. You will create a simple app using the Pleos Connect SDK. Through building a personalized safe driving score calculator app, you will learn step-by-step how to use the Vehicle SDK to integrate vehicle data.
This tutorial does not include design guidelines, UI implementation, or Android API integration details. Use this basic guide to create your own DIY vehicle app.
Development Level - Beginner
Basic knowledge of Android is recommended for smooth progress
Kotlin-based sample code guide provided
-
Prerequisite References:
-
Learning Objectives:
- Integrate vehicle data using the Pleos Vehicle SDK: API Details
-
Implementation Details: You will build a sample app that uses the Vehicle SDK to check car data and calculate a safe driving score. The app is designed for educational purposes.
The score calculation includes three penalty factors:
- Rapid acceleration: speed increases by 30km/h or more
- Sudden braking: speed decreases by 30km/h or more
- Poor steering: sharp changes of 50 degrees or more in either direction
You can extend the app with additional use cases using other Vehicle APIs.
Sample App Overview (Use this flow to build your own score calculator)
- Scoring begins when the gear is shifted to Drive mode and the vehicle accelerates.
- The initial score starts at 100 points. If a penalty condition is detected through vehicle status integration, 5 points are deducted each time.
- See the following section for how to simulate driving behavior using adb commands.
- Scoring ends when the vehicle decelerates to 0 speed and the gear is shifted to Parking mode.
- Final report shows number of infractions and total score:
- 100 P : Perfect Driver
- 70 P or more : Best Driver
- 50 P or more : Beginner Driver
- Below 50 P : Novice Driver
Development Environment Setup
Pleos Connect provides a development and testing environment for building infotainment applications.
Item | Version |
---|---|
Pleos Connect SDK | v2.0.5 |
Minimum Android SDK | Android API 26 or higher |
Gradle Version | 8.0 or higher |
Language | Java, Kotlin |
IDE | Android Studio |
AVD | Pleos Connect Emulator Setup Guide |
SDK Integration Setup
To use the Vehicle SDK, configure SDK dependencies and required permissions.
See Vehicle SDK Integration Guide for details.
Source Code Implementation
Implement code and configuration (permissions) to connect with vehicle data.
Since the sample app interacts with the driver during driving, you must declare Driver Distraction Optimized
as true in AndroidManifest.
For details, refer to the official Android guidelines.
Step 1. Declare SDK Permissions
Declare permissions in AndroidManifest.xml
to access vehicle speed and steering angle information.
The Pleos Connect SDK aligns with Android Automotive OS if there are equivalent or similar APIs to minimize platform fragmentation. If features from the Pleos SDK are later absorbed into Android Automotive, the SDK guarantees backward compatibility for at least two major versions.
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<!-- ... -->
<!-- TODO 2: Add dependencies and permissions (AndroidManifest.xml) -->
<uses-permission android:name="pleos.car.permission.CAR_DRIVE" />
<uses-permission android:name="android.car.permission.CAR_SPEED" />
<application />
<!-- ... -->
</manifest>
Step 2. Implement SDK Usage Code (Kotlin)
Using Vehicle SDK - Common (1/4)
Provide the Vehicle instance app-wide through a Hilt module using the @Provides method.
// package ai.pleos.playground.handson.vehicle.di.VehicleModules
@Module
@InstallIn(SingletonComponent::class)
object VehicleModules {
// TODO 3-1: Using Vehicle SDK - common
@Provides
@Singleton
fun provideVehicle(
@ApplicationContext context: Context
): Vehicle = Vehicle(context)
}
Using Vehicle SDK - Common (2/4)
Inject the Vehicle instance into MainActivity using @Inject.
// package ai.pleos.playground.handson.vehicle.MainActivity
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
// TODO 3-2: Using Vehicle SDK - common
@Inject
lateinit var vehicle: Vehicle
override fun onCreate(savedInstanceState: Bundle?) { /* ... */ }
override fun onDestroy() { /* ... */ }
}
Using Vehicle SDK - Common (3/4)
Initialize the SDK in onCreate().
// package ai.pleos.playground.handson.vehicle.MainActivity
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject
lateinit var vehicle: Vehicle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// TODO 3-3: Using Vehicle SDK - common
vehicle.initialize()
enableEdgeToEdge()
setContent { /* ... */ }
}
override fun onDestroy() { /* ... */ }
}
Using Vehicle SDK - Common (4/4)
Release SDK resources in onDestroy().
// package ai.pleos.playground.handson.vehicle.MainActivity
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject
lateinit var vehicle: Vehicle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
vehicle.initialize()
enableEdgeToEdge()
setContent { /* ... */ }
}
override fun onDestroy() {
super.onDestroy()
// TODO 3-4: Using Vehicle SDK - common
vehicle.release()
}
}
Using Vehicle SDK - Get Steering Wheel Angle API
Call getSteeringWheelAngle() from the ViewModel to fetch the current steering angle.
// package ai.pleos.playground.handson.vehicle.vm.MainViewModel
@HiltViewModel
class MainViewModel @Inject constructor(
private val carPropertyRepository: CarPropertyRepository,
private val vehicleSdkRepository: VehicleSdkRepository,
) : ViewModel() {
/* ... */
// TODO 4: Using Vehicle SDK - Get Steering Wheel Angle API
fun getSteeringWheelAngle() {
vehicleSdkRepository.getSteeringWheelAngle(
onSuccess = { angle ->
Log.d(logTag, "SteeringWheel Angle is $angle")
},
onFailure = { e ->
e.printStackTrace()
}
)
}
// ... 생략
}
Using Vehicle SDK - Callback Steering Wheel Angle API (1/2)
Implement a listener interface to receive callback when the steering wheel angle changes.
// package ai.pleos.playground.handson.vehicle.vm.MainViewModel
@HiltViewModel
class MainViewModel @Inject constructor(
private val carPropertyRepository: CarPropertyRepository,
private val vehicleSdkRepository: VehicleSdkRepository,
) : ViewModel() {
/* ... */
// TODO 5-1: Using Vehicle SDK - Callback Steering Wheel Angle API
private val steeringWheelAngleListener = object : SteeringWheelAngleListener {
override fun onFailed(e: Exception) {
Log.w(logTag, "SteeringWheel Angle onFailed called.", e)
}
override fun onSteeringWheelAngleUpdated(angle: Float?) {
if (angle != null) {
observeSteeringWheelAngle(angle)
}
}
}
// ... 생략
}
Using Vehicle SDK - Callback Steering Wheel Angle API (2/2)
Use a lambda or anonymous object to register the listener.
// package ai.pleos.playground.handson.vehicle.vm.MainViewModel
@HiltViewModel
class MainViewModel @Inject constructor(
private val carPropertyRepository: CarPropertyRepository,
private val vehicleSdkRepository: VehicleSdkRepository,
) : ViewModel() {
private val steeringWheelAngleListener = /* ... */
fun startEvent() {
// ...
// TODO 5-2: Using Vehicle SDK - Callback Steering Wheel Angle API
vehicleSdkRepository.registerSteeringWheelAngle(listener = steeringWheelAngleListener)
}
fun stopEvent() {
// ...
// TODO 5-2: Using Vehicle SDK - Callback Steering Wheel Angle API
vehicleSdkRepository.unregisterSteeringWheelAngle(listener = steeringWheelAngleListener)
}
// ...
}
Step 3. Test the App
- Run the sample app from Android Studio.
- Use adb commands to simulate vehicle states and test the app behavior.
adb root
adb shell "echo 'propId: {property id} areaId: {area id} values: {value}' > /data/vendor/vsomeip/vhal_fifo"
// array type
adb shell "echo 'propId: {property id} areaId: {area id} values: [{value1},{value2}]' > /data/vendor/vsomeip/vhal_fifo"
// Gear shift (GEAR_SELECTION)
// P (Park)
adb shell "echo 'propId: 289408000 areaId: 0 values: 4' >
/data/vendor/vsomeip/vhal_fifo"
// D (Drive)
adb shell "echo 'propId: 289408000 areaId: 0 values: 8' > /data/vendor/vsomeip/vhal_fifo"
/**
* Note: Speed must be provided in m/s.
* Example: 60km/h = 16.67m/s
* Property: PERF_VEHICLE_SPEED
*/
// Sudden acceleration/deceleration (change of 30 km/h or more)
adb shell "echo 'propId: 291504647 areaId: 0 values: {m/s}' > /data/vendor/vsomeip/vhal_fifo"
/**
* Note: Set value between min and max.
* min_value : -470
* max_value : 500
* Property: PERF_STEERING_ANGLE
*/
// Steering wheel change (must differ 50 degrees or more)
adb shell "echo 'propId: 291504649 areaId: 0 values: {min ~ max}' > /data/vendor/vsomeip/vhal_fifo"