Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 231 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

DriveQuant

Loading...

Loading...

Get started with drivekit

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Trip analysis

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

PERMISSIONS UTILS

Loading...

Loading...

iOS

Loading...

Loading...

Loading...

Loading...

Loading...

COMMON UI

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

DRIVER DATA

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

iOS

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Driver Data Timeline UI

Loading...

Loading...

Loading...

Android

Loading...

Vehicle

Loading...

iOS

iOS

This section describes how to integrate DriveKit into an iOS mobile application.

Requirements

DriveKit is developed with the Swift 5 language and is compatible with iOS 13.0 and later versions.

Trip recording lifecycle

Before you start, we recommend that you install the DriveKit Demo App and perform some testing to get familiar with the SDK's behavior and features.

The DriveKit Demo App integrates all components of the DriveKit SDK and you can refer to the code before installing the Trip Analysis component in your mobile application.

In order to understand how the smartphone telematics SDK works and how it will transform your app into a powerful sensor, take the time to read the following section that explains briefly the expected behavior.

Automatic trip recording

Before integrating the Trip Analysis component into your application, it is recommended that you understand how it works. This section explains the main states of the SDK during a trip as well as the events that trigger the transitions between states.

The diagram below shows, from top to bottom:

  • Events that trigger the transition from one state to another,

  • Main SDK states,

  • Accessible callbacks that your application can use to implement your own business logic.

Here is a brief description of the sequence of trip analysis from A to Z. Beneath the braces, the list contains all the methods that can be called at each stage of a trip's recording.

Trip Detection: the SDK does not start instantly at the beginning of the trip. There is a variable delay during which the application identifies that a trip might be in progress. If the probability is high enough, the application turns on the GPS sensor and starts to analyze the vehicle's speed.

Trip confirmation: the trip is not validated immediately. Beforehand, the SDK checks if the trip speed is consistent with that of a motor vehicle. If this is not the case, the trip will be canceled naturally and no data will be stored locally (and no data will be transmitted to the DriveQuant's server).

Trip Recording: if the trip is confirmed by the SDK, then the data are recorded locally for the entire trip.

End of Trip Detection: the SDK can determine if the trip is completed. Each time the vehicle stops, a timer starts to check whether the stop is definitive or not. Depending on your needs, it is possible to set a time delay for stopping a trip. The default timeout value is 4 minutes. You can adjust this value between 2 and 8 minutes.

Trip Analysis: once the trip has been completed, the SDKs automate the request to the trip analysis API. If the smartphone is not connected to a mobile network, the request will be retried later.

Mobile data usage

The use of the DriveQuant SDK has a minimal impact on the driver's smartphone data plan. Data consumption is a topic that users of your application may be concerned about, so we have done our best to limit the amount of data used by the SDK.

The trip data are recorded with a frequency of 1Hz and are transmitted in text format. The volume of data recorded is about 5 kb per minute of driving:

  • 50 kb of data are used for the analysis of a short 10-minute trip,

  • 150 kb of data are used for the analysis of a 30-minute trip,

  • A 2-hour long trip uses 600 kb of data.

The average data usage for a commuter working 30 minutes from home will be in the range of 10 Mb to 12 Mb per month.

Battery consumption

The DriveKit SDK measures data from smartphone sensors while minimizing the impact on the battery. It automatically detects the start and end of a motorized trip and does not use the GPS sensor outside of the trip.

This helps to avoid draining the phone's battery and protects the user's privacy. Location data from the phone are not collected outside of the phases where the user is driving.

Advanced configurations

Manually initialize the SDK

By default, the DriveKit SDK is automatically initialized as soon as you add the TripAnalysis module to your project.

In some cases, you may want to manually initialize the SDK. To do this, you have to disable the automatic initialization by adding the key DKAutoInitEnabled associated to the Boolean value false into the Info.plist file:

<key>DKAutoInitEnabled</key>
<false/>

Then, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    DriveKit.shared.initialize()
    DriveKitTripAnalysis.shared.initialize(appLaunchOptions: launchOptions)
    (…)
}

The DriveKit modules include a method initialize that must be called in didFinishLaunchingWithOptions method of your AppDelegate if you have decided to manually initialize the SDK.

Check your configuration

You can check if DriveKit is well configured with the following method:

func isConfigured() -> Bool

This method returns true if these three conditions are met:

  • DriveKit Core is initialized

  • an API key is set

  • a userId is set

Check if user is authenticated

You can check if the user is connected by calling the following method:

func isUserConnected() -> Bool

This method returns true if the user is authenticated to DriveKit.

Logging

DriveKit comes with a logging feature that is enabled by default. This feature allows you to quickly identify the cause of a problem. We recommend leaving the log enabled as it does not consume memory space and is useful in the support phase. However, if you don't want to use it, it can be disabled.

Log will be written in app directory. One log file per month will be written with the name log-<YEAR>-<MONTH>.txt (example: log-2019-8.txt). All DriveKit modules log in this file. You can get a zip file with the log files of the previous month and the current one with the method DriveKitLog.shared.getZippedLogFilesUrl(), or by clicking on “Contact support” and changing the email receiver. The file will be in attachment of the email.

To be able to access logs from Files app, you must add the following entries in your Info.plist file: UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace, setting both to true.

Disable logging by calling the following method:

func disableLogging(showInConsole: Bool = true)

To activate logging, call the following method:

func enableLogging(showInConsole: Bool = true)

Listen for permissions and sensors status changes

If the user disables the sensors or revokes permissions, the application would not be able to detect and record a trip. To avoid this, the SDK identifies important sensor state and permission changes.

These events are shared and you can use them in your application to inform the user via a visual alert or by displaying a notification.

Event changes callbacks may not be fired in real time due to technical restrictions of iOS.

DKDeviceConfigurationDelegate

DKDeviceConfigurationDelegate is a protocol used to get callbacks when device configuration changes are detected:

protocol DKDeviceConfigurationDelegate: AnyObject {
    func deviceConfigurationDidChange(event: DKDeviceConfigurationEvent)
}

Add a delegate

func addDeviceConfigurationDelegate(_ delegate: DKDeviceConfigurationDelegate)

Remove a delegate

To remove a specific delegate, call the following method:

func removeDeviceConfigurationDelegate(_ delegate: DKDeviceConfigurationDelegate)

Remove all delegates

To remove all delegates, call the following method:

func removeAllDeviceConfigurationDelegates()

DKDeviceConfigurationEvent

DKDeviceConfigurationEvent is a class describing a device configuration event.

class DKDeviceConfigurationEvent {
    let type: DKDeviceConfigurationEventType
    let isValid: Bool
}
Attribute
Type
Description

type

Enum

isValid

Boolean

Boolean describing whether the device configuration event is valid or not

DKDeviceConfigurationEventType

public enum DKDeviceConfigurationEventType {
    case activityPermission
    case locationPermission
    case bluetoothPermission
    case notificationPermission
    case lowPowerMode
    case locationSensor
    case bluetoothSensor
}

Possible types are:

Event type
Description

activityPermission

Motion & Fitness permission status changed

locationPermission

Location permission status changed

bluetoothPermission

Bluetooth permission status changed

notificationPermission

Notifications permission status changed

lowPowerMode

Low Power Mode status changed

locationSensor

Location sensor status changed

bluetoothSensor

Bluetooth sensor status changed

The DriveKit SDK will run optimally if the isValid value of each event is true. The table below explains the impact of a status that is not true.

Event
Criticality
Consequence if value is false

LocationPermission

🔴

No trip recording if app has no access to GPS sensor

BluetoothPermission

🟡

No trip detection based on Bluetooth system

ActivityPermission

🟡

Detected transportation mode mode can be inaccurate when no access to this permission

NotificationPermission

🟢

Your application cannot send notification to the user if the permission is revoked.

lowPowerMode

🟢

No considerable impact

LocationSensor

🔴

No trip recording if GPS sensor is disabled

BluetoothSensor

🟡

No trip detection based on Bluetooth system. Can also impact beacon trip detection.

Get user’s information

To get user’s information (first name, last name and pseudo), call the getUserInfo method. It will retrieve and save these data locally:

DriveKit.shared.getUserInfo(synchronizationType: .defaultSync) { status, userInfo in
    if status == .success {
        // Get user's names in userInfo object.
    }
}

Update user’s information

You can add information to a user's account such as first name, last name and pseudo. These details are optional and you can choose to make the user's account anonymous. To update the user's information, you must call the updateUserInfo method:

DriveKit.shared.updateUserInfo(pseudo: "New_pseudo") { success in
    if success {
        // The pseudo has been successfully updated.
    }
}

Or to update all information:

DriveKit.shared.updateUserInfo(firstname: "New_firstname", lastname: "New_lastname", pseudo: "New_pseudo") { success in
    if success {
        // The firstname, lastname and pseudo have been successfully updated.
    }
}

Update UserId

It is possible to update the userId by calling the following method:

func updateUserId(userId: String)

Account deletion

You can delete a driver's account in DriveKit. This action deletes all the data related to the account.

The deletion can be done instantly or with delay.

  • In the first case, when the method is called, the account is instantly deleted.

  • In the second case, the driver has 30 days to log back into the application and reactivate his account.

To delete a driver's account, use the following method:

func deleteAccount(instantDeletion: Bool = false)

instantDeletion can have 2 values:

  • false : Default value, allows the user to recover the deleted account by logging-in again with the same credentials. Users have 30 days starting from the day when the account was deleted.

  • true : Allow to delete an account instantly. The account and all the related data will be immediately deleted and no rollback is possible.

Your team needs to have the deletion feature activated to use this method. Please contact DriveQuant if you need it.

You should restore the DriveKit API key in the onAccountDeleted() callback only when the status value is SUCCESS.

Retrieving the installation identifier

The installation identifier (installationId) is not a unique device identifier. It is used to identify an app installation that includes the DriveKit SDK, linked to a specific account on a particular device.

The installationId is generated based on the following attributes:

  • Installation date

  • App

  • User account

  • Device type

The installationId helps determine whether a user has logged into a mobile app with the same account across multiple devices.

For a user with one account and a single device, the installationId behaves as follows:

  • It remains unchanged if the user logs out and logs back in, as long as the app is not uninstalled.

  • It is updated when the user uninstalls and reinstalls the app.

If a user logs into the app on several devices using the same account, each device will have a different installationId.

If the user reconnects to the app on the same device but with a different account, the installationId will be updated.

The installationId uses the UUID format. Example: 123e4567-e89b-12d3-a456-426614174000

You can retrieve the installationId by calling the following computed property:

var installationId: String?

The returned installationId will be nil as long as the user is not authenticated to DriveKit.

Reset

If you need to reset DriveKit configuration (user logout for example), you can call the following method:

DriveKit.shared.reset()

All data saved locally will be erased and default configuration for every module will be restored.

Introducing DriveKit

A quick overview of DriveKit to understand the main features and principles.

This documentation is for developers. Follow the simple guideline to install our telematics SDK and access powerful insight and actionable data.

What is DriveKit?

DriveKit is a modularized software suite for creating mobile applications to engage and coach drivers.

DriveKit is composed of SDK available on both iOS and Android platforms and web services (REST API) that are designed to collect, analyze, organize, store and display driving data.

DriveKit is a 100% mobile telematics technology based on smartphone sensors to analyze vehicle trips and evaluate the influence of driving style on safety and energy consumption.

How does it work?

The DriveKit SDK transforms any iOS or Android application into a data collection solution to measure and improve driving behavior.

The SDK provides automatic detection of vehicle trips and recording of GPS data locally during the trip.

At the end of a trip, the SDK automatically requests the data analysis services embedded on the DriveQuant platform.

The DriveQuant platform contains the signal processing algorithms and databases where raw data and driving indicators resulting from the analyzes are stored.

The results of a trip analysis are usually returned to the application within seconds after the end of the trip.

The SDK contains a local database that is automatically and continuously synchronized with the DriveQuant platform database.

What are the main features included in the mobile SDK?

The DriveKit SDK is a set of independent features integrated into modules.

Some of these modules include graphical libraries with user interfaces.

The table below summarizes all the modules included in DriveKit:

Module
Description
UI

Core

SDK management: authentication, user creation, diagnostic functions (logs, permissions and sensors status).

❌

Recording of sensor signals and automatic trip detection.

✅

Synchronisation of all user data in the local SDK database.

✅

Configuration of one or more vehicles linked to a user's account.

✅

Graphical interfaces that help to collect the user permissions to run the SDK.

✅

Management of driving challenges.

✅

User engagement features: ranking, badge and streaks

✅

Not all the DriveKit SDK modules listed in this table are strictly necessary. The key modules for transforming your application into a telematics solution are: Core and Trip Analysis.

If you plan to display the driving analysis results in your mobile application, we strongly recommend that you install the Driver Data module, which synchronizes all a driver's trips, synthesis and historical data.

What are the advantages of DriveKit?

  • 100% mobile and high-performance telematics solution.

  • Easy and quick integration.

  • Automatic trip recording.

  • Optimized battery consumption.

  • Minimal use of data.

  • Built-in database with automatic synchronization.

  • A wide range of analytics and services.

  • Plug-and-play user interfaces.

The DriveKit Demo App

Contact us

You can find all resources on .

Android DriveKit Demo App can be found .

iOS DriveKit Demo App can be found .

The DriveKit SDK ( component) has the ability to automatically detect and record a trip when your application runs in background.

You can also make files of your application (including DriveKit log files) available in the by adding these 2 keys to your project's Info.plist file: UIFileSharingEnabled and LSSupportsOpeningDocumentsInPlace, setting them both to true.

To add a delegate and listen for , you can call the following function:

enum describing the type of event

To be able to check whenever userId got updated and catch the update status, you have to use delegate.

To be able to check whenever the account deletion is complete, you have to use the interface.

For example, you can retrieve the identifier after the driveKitDidConnect() callback is triggered. (Read more about the )

In addition to data analysis, DriveKit allows you to easily and quickly integrate features into your application to help drivers improve and manage their vehicles on a daily basis: coaching, ludic functions, mileage monitoring, car maintenance. All these features can be tested in our demo application (on and ).

To better understand how the DriveKit SDK is working, we recommend you to test the DriveKit Demo app. It contains all the DriveKit SDK components and has been developed to guide mobile developers to understand how DriveQuant's telematics solution works. The DriveKit Demo App is available on GitHub for and .

The DriveKit Demo App needs credential. Please, contact us to get your API key via:

You can contact DriveQuant via email at to request a demonstration, to be supported during the integration phase or to get answers to any specific requests.

Github
here
here
TRIP ANALYSIS
iOS Files app
DriveKitDelegate
iOS
Android
iOS
Android
contact@drivequant.com
contact@drivequant.com
Device Configuration Events
Trip Analysis
Driver Data
Vehicle
Permissions Utils
Challenge
Driver Achievement
DKDeviceConfigurationEventType

Android

Requirements

DriveKit is developed with the Kotlin language and is compatible with Android 8.0 (API 26) and later versions.

Please ensure that others libraries integrated in your project are compatible with these versions ; for example if you use a library to manage runtime permissions.

DriveKit uses the libraries listed below. These are minimal required versions. Check that they are compatible with your app:

References

DriveKitListener

UpdateUserIdStatus

UpdateUserIdStatus is an enum that explains the request status after a userId has asked to be changed.

RequestError

RequestError is an enum that describes the error type of a DriveKit request.

DeleteAccountStatus

DeleteAccountStatus is an enum that describes the deletion status. It can have 3 values:

  • SUCCESS: Account deleted successfully

  • FAILED_TO_DELETE: Account not deleted, an error has occurred

  • FORBIDDEN: Account deletion not activated for this team

DKWeather

DKWeather is an enum that describe each category of weather during a trip. It can have these values:

  • UNKNOWN

  • SUN

  • CLOUD

  • FOG

  • RAIN

  • SNOW

  • ICE

Advanced configurations

Manually initialize the SDK

By default, the DriveKit SDK is automatically initialized as soon as you add the TripAnalysis module to your project.

In some cases, you may want to manually initialize the SDK. To do this you have to disable the automatic initialization by adding the following lines into your Manifest file:

Then, you must call the initialization methods in the onCreate method of your Application class:

Check your configuration

You can check if DriveKit is well configured with the following method:

This method returns true if these three conditions are met:

  • DriveKit Core is initialized

  • an API key is set

  • a userId is set

Check if user is authenticated

You can check if the user is connected by calling the following method:

This method returns true if the user is authenticated to DriveKit.

Logging

DriveKit comes with a logging feature that is enabled by default. This feature allows you to quickly identify the cause of a problem. We recommend leaving the log enabled as it does not consume memory space and is useful in the support phase. However, if you don't want to use it, it can be disabled.

You can retrieve the Uri log file by calling the following method on DriveKitLog class:

If your device version is on Android 10 or below, you can directly find the log file in Android/data/<your-app-package-name>/files/<path-to-my-log-directory>

If your device version is on Android 11 and above and if you have The Permissions Utils component on your app, you can get a log file of the previous month and the current one with the method getZippedLogUriFiles(), or by clicking on “Contact support” and change the email receiver. The file will be in attachment of the email.

Disable logging by calling the following method on DriveKit class:

To enable logging, call the following method on DriveKit class, specifying (if needed) the path of the log directory:

Listen for permissions and sensors status changes

If the user disables the sensors or revokes permissions, the application would not be able to detect and record a trip. To avoid this, the SDK identifies important sensor state and permission changes.

These events are shared when the user is logged in and you can use them in your application to inform the user via a visual alert or by displaying a notification.

Event changes callbacks may not be fired in real time due to technical restrictions of Android.

DKDeviceConfigurationListener

DKDeviceConfigurationListener is the interface used to get callbacks when device configuration changes are detected:

Add a listener

Remove a listener

To remove a specific listener, call the following method:

Remove all listeners

To remove all listeners, call the following method:

DKDeviceConfigurationEvent

DKDeviceConfigurationEvent is a sealed class that describes a device configuration change event:

Possible events are:

The DriveKit SDK will run optimally if the isValid value of each event is true. The table below explains the impact of a status that is not true:

Get user’s information

To get the user's information (first name, last name and pseudo), call the getUserInfo method. This method will retrieve and save these data locally:

Update user’s information

You can add information to a user's account such as first name, last name and pseudo.

These details are optional and you can choose to make the user's account anonymous. To update the user's information, call the following method :

Update UserId

It is possible to update the userId by calling the following method:

Account deletion

You can delete a driver's account in DriveKit. This action deletes all the data related to the account.

The deletion can be done instantly or with delay.

  • In the first case, when the method is called, the account is instantly deleted.

  • In the second case, the driver has 30 days to log back into the application and reactivate his account.

To delete a driver's account, use the following method:

instantDeletion can have 2 values:

  • false : Default value, allows the user to recover the deleted account by logging-in again with the same credentials. Users have 30 days starting from the day when the account was deleted.

  • true : Allow to delete an account instantly. The account and all the related data will be immediately deleted and no rollback is possible.

Your team needs to have the deletion feature activated to use this method. Please contact DriveQuant if you need it.

You should restore the DriveKit API key in the onAccountDeleted() callback only when the status value is SUCCESS.

Retrieving the installation identifier

The installation identifier (installationId) is not a unique device identifier. It is used to identify an app installation that includes the DriveKit SDK, linked to a specific account on a particular device.

The installationId is generated based on the following attributes:

  • Installation date

  • App

  • User account

  • Device type

The installationId helps determine whether a user has logged into a mobile app with the same account across multiple devices.

For a user with one account and a single device, the installationId behaves as follows:

  • It remains unchanged if the user logs out and logs back in, as long as the app is not uninstalled.

  • It is updated when the user uninstalls and reinstalls the app.

If a user logs into the app on several devices using the same account, each device will have a different installationId.

If the user reconnects to the app on the same device but with a different account, the installationId will be updated.

The installationId uses the UUID format. Example: 123e4567-e89b-12d3-a456-426614174000

You can retrieve the installationId by calling the following computed property:

The returned installationId will be null as long as the user is not authenticated to DriveKit.

Reset

If you need to reset DriveKit configuration (user logout for example), you can call the following method:

All data saved locally will be erased and default configuration for every module will be restored.

The DriveKit SDK version is configured with these attributes:

Android SDK version property
API level
Library
Version

DriveKit uses . If you use , you need to add android:fullBackupOnly in your .

DriveKitListener is an interface that can be passed as a parameter during the DriveKit Core module . It gives useful events about the user lifecycle.

Method
Description
Value
Description
Value
Description

To add a listener and get informed for , you can call the following method:

Value
Description
Event
Criticality
Consequence if value is false

To be able to check whenever userId got updated and catch the update status you have to use listener.

To be able to check whenever the account deletion is complete, you have to use the interface.

For example, you can retrieve the identifier after the onConnected() callback is triggered. (Read more about the )

minSdkVersion

26 (Android 8)

compileSdkVersion

35 (Android 15)

targetSdkVersion

35 (Android 15)

Kotlin

1.8.22

Java

17

Gson

2.10.1

Volley

1.2.1

Room

2.5.2

Work Manager

2.9.0

Play Services Location

21.0.1

interface DriveKitListener {
    fun onConnected()
    fun onDisconnected()
    fun onAuthenticationError(errorType: RequestError)
    fun userIdUpdateStatus(status: UpdateUserIdStatus, userId:String?)
    fun onAccountDeleted(status: DeleteAccountStatus)
}
enum class UpdateUserIdStatus {
    UPDATED, FAILED_TO_UPDATE, INVALID_USER_ID, ALREADY_USED, SAVED_FOR_REPOST
}

UPDATED

The userId has been successfully updated

FAILED_TO_UPDATE

Occurs when DriveKit is not configured yet or if the new userId is the same as the old one

INVALID_USER_ID

Error returned when the new userId is blank

ALREADY_USED

The new userId is already taken by another user

SAVED_FOR_REPOST

The request failed but a retry will be done

enum class RequestError {
    NO_NETWORK, UNAUTHENTICATED, FORBIDDEN, SERVER_ERROR, CLIENT_ERROR, UNKNOWN_ERROR, LIMIT_REACHED
}

NO_NETWORK

The user has no or a bad connection during the request.

UNAUTHENTICATED

A request has been launched but the user is not logged (401 error).

FORBIDDEN

A 403 error occurred. You might don't have access to call that service. Please contact the DriveQuant to learn more.

SERVER_ERROR

Drivequant's backend responds with a 500 server error.

CLIENT_ERROR

Drivequant's backend responds with a 400 error different than UNAUTHENTICATED, FORBIDDEN and LIMIT_REACHED

UNKNOWN_ERROR

An unknown error occurred, please contact the Drivequant team to investigate the issue.

LIMIT_REACHED

The DriveKit API key has reached the accounts number limit. Please contact the Drivequant team.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        ...
        <meta-data
            android:name="com.drivekit.sdk.auto_init_enabled"
            android:value="false" />
    </application>
</manifest>
class MyApplication: Application() {
    override fun onCreate() {
        ...
        DriveKit.initialize()

        val tripNotification: TripNotification = ...
        DriveKitTripAnalysis.initialize(tripNotification)

        // Initialize every other DriveKit modules you use:
        // DriveKitDriverData.initialize()
        // DriveKitVehicle.initialize()
        // etc.
    }
}
fun isConfigured(): Boolean
fun isUserConnected(): Boolean
fun getLogUriFile(context: Context): Uri?
fun disableLogging(showInConsole: Boolean = true)
fun enableLogging(logPath: String = "/DriveKit", showInConsole: Boolean = true)
interface DKDeviceConfigurationListener {
    fun onDeviceConfigurationChanged(event: DKDeviceConfigurationEvent)
}
fun addDeviceConfigurationListener(listener: DKDeviceConfigurationListener)
fun removeDeviceConfigurationListener(listener: DKDeviceConfigurationListener)
fun removeAllDeviceConfigurationListeners()
sealed class DKDeviceConfigurationEvent {
	data class LocationPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class ActivityPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class NearbyDevicesPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class NotificationPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class AutoResetPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class AppBatteryOptimisation(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class LocationSensor(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class BluetoothSensor(val isValid: Boolean) : DKDeviceConfigurationEvent()
}

LocationPermission

Location permission status changed

ActivityPermission

Activity Recognition permission status changed

NearbyDevicesPermission

Nearby Devices permission status changed

NotificationPermission

Notification permission status changed

AutoResetPermission

Auto-reset permission status changed

AppBatteryOptimization

Battery Optimization app status changed

LocationSensor

Location sensor status changed

BluetoothSensor

Bluetooth sensor status changed

LocationPermission

🔴

No trip recording if app has no access to GPS sensor

ActivityPermission

🟡

Poor trip detection

NearbyDevicesPermission

🟡

No trip detection based on beacon or Bluetooth system

NotificationPermission

🟢

Your application cannot send notification to the user if the permission is revoked.

AutoResetPermission

🟢

Revocation of all permissions if app is not opened for 3 months.

AppBatteryOptimization

🟡

Poor trip detection, application may be killed in background

LocationSensor

🔴

No trip recording if location sensor is disabled

BluetoothSensor

🟡

No trip detection based on beacon or Bluetooth system

fun getUserInfo(
        listener: GetUserInfoQueryListener,
        synchronizationType: SynchronizationType = SynchronizationType.DEFAULT
)
fun updateUserInfo(
        firstname: String? = null,
        lastname: String? = null,
        pseudo: String? = null,
        listener: UpdateUserInfoQueryListener
)
fun updateUserId(userId: String)
fun deleteAccount(instantDeletion: Boolean = false)
var installationId: String?
fun reset()
latest
key-value backup
Auto Backup
Manifest
initialization
DriveKitListener
device configuration events
DriveKitListener
DriveKitListener

onConnected()

The user has been successfully logged

onDisconnected()

The user has been disconnected (manual logout or the account is disabled/deleted)

onAuthenticationError(errorType: RequestError)

userIdUpdateStatus(status: UpdateUserIdStatus, userId:String?)

onAccountDeleted(status: DeleteAccountStatus)

The delete account request has been processed with a DeleteAccountStatus state value

DriveKit Guides

The DriveKit guides explain step by step how to install and use DriveKit. It's available on iOS and Android or via a REST API.

iOS guides

Get started for Swift

Android guides

Get started for Kotlin and Java

REST API

All services used by DriveKit Mobile SDK are also available through REST services. For each SDK you will find the description of web services in the REST services section.

Introduction

The trip analysis API transforms GPS data collected by a smartphone or any other telematics system into actionable driver and vehicle analytics.

The API provides a broad range of indicators that depends on your subscription. DriveKit's trip analysis API provides more than 200 indicators per trip. They are organized by categories so that you can choose the ones that best suit your use case. The categories of driving indicators are listed below.

Data that represent the driver's behavior:

  • Eco-driving score.

  • Safety score.

  • Distraction score (phone use).

  • Speed limits score.

Data that measure the impact of driving behavior on the vehicle:

  • Fuel consumption.

  • Pollutant emissions.

  • Tires and brakes wear.

Additional data describing the context of the trip:

  • Departure and arrival adresses and dates.

  • Average speed.

  • Driving context.

  • Weather.

The Trip analysis component also contains an accident detection feature that uses the smartphone's sensors to automatically detect if the vehicle has been involved in a crash. Smartphone-based accident detection allows you to:

  • offer a driver assistance solution integrated into your application;

  • access accurate data to speed up claims management.

References

DriveKitDelegate

UpdateUserIdStatus

UpdateUserIdStatus is an enum that explains the request status after a userId has asked to be changed.

RequestError

RequestError is an enum that describes the error type of a DriveKit request.

DeleteAccountStatus

DeleteAccountStatus is an enum that describes the deletion status. It can have 3 values:

  • success: Account deleted successfully

  • failedToDelete: Account not deleted, an error has occurred

  • forbidden: Account deletion not activated for this team

DKWeather

DKWeather is an enum that describe each category of weather during a trip. It can have these values:

  • unknown

  • sun

  • cloud

  • fog

  • rain

  • snow

  • ice

The login has failed due to a

The update userId request has been processed with a state value

This API is automatically queried by the mobile SDKs as soon as a trip is completed. The results are returned, after a few seconds, to the SDK and can also be transmitted via a to a third-party server.

We recommend you to test this component in the before you integrate it in your application.

DriveKitDelegate is a protocol that can be passed as a parameter during the . It gives useful events about the user lifecycle.

Method
Description
Value
Description
Value
Description
iOS
Android
push data service
RequestError
UpdateUserIdStatus
DriveKit Demo App
protocol DriveKitDelegate: AnyObject {
    func driveKitDidConnect(_ driveKit: DriveKit)
    func driveKitDidDisconnect(_ driveKit: DriveKit)
    func driveKit(_ driveKit: DriveKit, didReceiveAuthenticationError error: RequestError)
    func userIdUpdateStatusChanged(status: UpdateUserIdStatus, userId: String?)
    func driveKit(_ driveKit: DriveKit, accountDeletionCompleted status: DeleteAccountStatus)
}

driveKitDidConnect(_ driveKit: DriveKit)

The user has been successfully logged

driveKitDidDisconnect(_ driveKit: DriveKit)

The user has been disconnected (manual logout or the account is disabled/deleted)

driveKit(_ driveKit: DriveKit, didReceiveAuthenticationError error: RequestError)

The login has failed due to a RequestError

userIdUpdateStatusChanged(status: UpdateUserIdStatus, userId: String?)

The update userId request has been processed with a UpdateUserIdStatus state value

onAccountDeleted(status: DeleteAccountStatus)

The delete account request has been processed with a DeleteAccountStatus state value.

public enum UpdateUserIdStatus: Int {
    case updated
    case failedToUpdate
    case invalidUserId
    case alreadyUsed
    case savedForRepost
}

updated

The userId has been successfully updated

failedToUpdate

Occurs when DriveKit is not configured yet or if the new userId is the same as the old one

invalidUserId

Error returned when the new userId is blank

alreadyUsed

The new userId is already taken by another user

savedForRepost

The request failed but a retry will be done

public enum RequestError: Int {
    case noNetwork
    case unauthenticated
    case forbidden
    case serverError
    case clientError
    case limitReached
    case unknownError
}

noNetwork

The user has no connection or a bad one during the request.

unauthenticated

A request has been launched but the user is not logged (401 error).

forbidden

A 403 error occurred. You might don't have access to call that service. Please contact the DriveQuant to learn more.

serverError

Drivequant's backend responds with a 500 server error.

clientError

Drivequant's backend responds with a 400 error different than unauthenticated, forbidden and limitReached

unknownError

An unknown error occurred, please contact the Drivequant team to investigate the issue.

limitReached

The DriveKit API key has reached the accounts number limit. Please contact the Drivequant team.

DriveKitDelegate
DriveKitDelegate
DriveKit Core module initialization

iOS

Trip management

Trip autostart

The automatic mode detects vehicle movements and triggers the trip analysis without driver intervention while the application is in background. The analysis is stopped automatically at the end of the trip.

This feature is recommended to avoid driver distraction and phone handling while driving. The automatic mode has been optimized to limit the battery drain.

By default, automatic trip detection is disabled, but you can enable it by calling the following method:

DriveKitTripAnalysis.shared.activateAutoStart(enable: true)

To disable automatic trip detection call the same method with parameter enable set to false

DriveKitTripAnalysis.shared.activateAutoStart(enable: false)

Manually start a trip

You can start a trip by calling the following method:

DriveKitTripAnalysis.shared.startTrip()

If a trip's already started, calling this method will have no effect.

Stop a trip

You can stop a trip by calling the following method. The trip will be stopped instantly:

DriveKitTripAnalysis.shared.stopTrip()

If there is no running trip, calling this method will have no effect.

Cancel a trip

If you want to cancel a trip, you can call this method:

DriveKitTripAnalysis.shared.cancelTrip()

If no trip is running or if the trip has been sent to the server and is currently analyzed, calling this method will have no effect.

Vehicle

To obtain a more precise analysis on driving behavior, it's recommended to configure the vehicle used by the driver. You can do this by calling the following method:

DriveKitTripAnalysis.shared.setVehicle(vehicle: TripVehicle?)

If no vehicle is configured a default vehicle will be configured with following parameters:

  • carTypeIndex = 1

  • carEngineIndex = 1

  • carPower = 150

  • carMass = 1400

  • carGearboxIndex = 2

  • carConsumption = 4.5

  • engineDisplacement = 1200

  • frontTireSize = "205/55/16"

  • rearTireSize = "205/55/16"

  • length = 4.5

  • width = 1.8

  • height = 1.45

  • engineCylinderNb = 4

  • driveWheels = 0

SDK recorder state

Two methods are available to determine SDK state.

DriveKitTripAnalysis.shared.isTripRunning()

This method returns false if the SDK is in inactive state, and no trip is currently running.

If you want a more detailed state of the SDK, you can call the following method:

DriveKitTripAnalysis.shared.getRecorderState()

This method returns the state of the SDK:

  • inactive: No trip is running.

  • starting: The auto start mode detects a movement of the user and checks if it's a trip in vehicle.

  • running: The trip has been confirmed by the speed of the movement.

  • stopping: The SDK is in this state when a potential trip end is detected. If the trip continues, the SDK goes back in running state. The duration of the stopping state can be configured.

  • sending: The trip is finished and is being sent to DriveQuant's server. When the SDK has the response from the server, the state becomes inactive waiting for the next trip.

Get information about the current trip

When a trip analysis is starting, you may need some information about it, like the StartMode which triggers the trip recording, a local unique identifier of the trip that has not yet been analyzed by the DriveQuant’s servers, etc.

  • The local unique identifier generated by the SDK (localTripId) is different from the unique trip identifier generated after data analysis (itinId).

  • A local trip identifier generated by the SDK (localTripId) is linked to a single unique trip identifier (itinId).

  • If the trip is cancelled locally, there will be no trip analysis and therefore no unique trip identifier (itinId) linked to the unique local identifier (localTripId).

To retrieve information about the current trip, use the following method:

func getCurrentTripInfo() -> DKTripInfo?

The method can return nil if there is no trip currently recording.

DKTripInfo

Property
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK.

⚠️ It is different from the itinId property returned in the Trip object. itinId corresponds to the unique trip identifier generated after the data analysis.

date

Date

Start date of the trip analysis.

startMode

StartMode

Manual trip repost

Trip Analysis SDK have a repost mechanism, in most cases, when a trip is finished it is sent to DriveQuant's server to be analyzed and once it's done, the result of the analysis is sent back to the SDK.

In some case, the trip can't be sent to the server (no network for example). In this case, the SDK will save the trip data locally, to send it later. A retry will be attempted when the next trip will start.

If you want to check if there is locally saved trips and if they can be sent to the server, you can call the following method:

DriveKitTripAnalysis.shared.checkTripToRepost()

Custom stop timeout

A trip being analyzed is automatically stopped after a period of inactivity (which begins when the vehicle has stopped). The DriveQuant SDK allows to set the end-of-trip duration.

By default, the trip analysis is stopped after 240 seconds. This value can be tuned according to your need and you can choose any integer values between 120 and 480 seconds by calling the following method:

DriveKitTripAnalysis.shared.setStopTimeOut(timeOut: 180)

If a value greater than 480 is set, the value will be forced to 480.

If a value lower than 120 is set, the value will be forced to 120.

Manage the location sharing while driving

Thanks to the driving location sharing feature, a user can generate a link that directs to a map displaying its location while driving. Location sharing provides peace of mind to family members during a trip. This section describes the methods to manage the location-sharing link.

Check if the feature is available

If the trip sharing feature is enabled for your company, your API key carries out the feature access and a trip sharing link can be generated.

To check if the trip sharing feature is available for your API key, you can call the following code:

DriveKitTripAnalysis.shared.tripSharing.isAvailable()

Create a link

To generate a link to share trips, use the following code:

let oneHourInSeconds = 3600
DriveKitTripAnalysis.shared.tripSharing.createLink(durationInSeconds: oneHourInSeconds) { status, data in
    // Check the status and manage the data
}

The method takes a durationInSeconds parameter which indicates how long in seconds from now the sharing link will be valid.

CreateTripSharingLinkStatus

Value
Description

success

The link has been successfully created. Information is returned in data.

activeLinkAlreadyExists

A link already exists for this user.

Information returned in data is nil.

error

An error occurred, for instance when the user has no network.

Information returned in data is nil.

userNotConnected

The user is not yet connected to DriveKit. Information returned in data is nil.

invalidDuration

An error occurred when trying to create a link. The duration parameter must be strictly greater than 0. Information returned in data is nil.

unauthenticated

The user has been disconnected.

Information returned in data is nil.

forbidden

Your API key is not allowed to use the feature.

Information returned in data is nil.

DKTripSharingLink

Property
Type
Description

code

String

Unique trip sharing code.

url

String

URL of the map that will display the current trip of the user.

startDate

Date

Link validity start date

endDate

Date

Link expiration date.

Retrieve a valid sharing link

To retrieve a link to share trips, use the following code:

DriveKitTripAnalysis.shared.tripSharing.getLink(synchronizationType: .defaultSync) { status, data in
    // Check the status and manage the data
}

The method takes a synchronizationType parameter. It will retrieve locally stored data if the value is .cache, otherwise with the .defaultSync value it will call the DriveQuant’s servers.

GetTripSharingLinkStatus

Value
Description

success

The link has been successfully retrieved. Information is returned in data.

failedToGetCacheOnly

An error occurred when trying to retrieve a link. Locally trip sharing link, if exists, is returned in data.

noActiveLink

There is no active link for the user.

Information returned in data is nil.

userNotConnected

The user is not yet connected to DriveKit. Information returned in data is nil.

unauthenticated

The user has been disconnected.

Information returned in data is nil.

forbidden

Your API key is not allowed to use the feature.

Information returned in data is nil.

Revoke a trip sharing link

To revoke a trip sharing link, use the following code:

DriveKitTripAnalysis.shared.tripSharing.revokeLink { status in
    // Check the status
}

RevokeTripSharingLinkStatus

Value
Description

success

The link has been successfully revoked.

noActiveLink

There is no active link for the user.

error

An error occurred when trying to revoke the link.

userNotConnected

The user is not yet connected to DriveKit.

unauthenticated

The user has been disconnected.

forbidden

Your API key is not allowed to use the feature.

Sharing data during the trip

The Trip Analysis SDK records the trip locally while it is in progress. The data are recorded with a period of one point per second. At the end of the trip, the SDK requests the driving analysis service and then retrieves the driving indicators.

In addition to this feature, the SDK is also able to share data with the server before the journey is completed. The data is transmitted at a lower frequency with a time interval of one point per minute.

Sharing information with the server allows you to store the trip data even if it's been interrupted and the data post could not be performed at the end of the trip. This can happen in very rare cases such as the destruction of the mobile phone for instance.

By default, this setting is disabled but you can enable it by calling the following method:

DriveKitTripAnalysis.shared.enableSharePosition(enable: true)

To disable this setting, call the same method with the parameter set to false

DriveKitTripAnalysis.shared.enableSharePosition(enable: false)

Here is the list of data shared every minute by the SDK:

  • Date of trip start.

  • Duration of the trip in seconds.

  • Distance traveled in km.

  • Longitude of the current location.

  • Latitude of the current location.

  • Smartphone battery level.

  • Start-Mode for trip recording: manual, GPS-based or beacon-based.

  • Beacon parameters: uuid, major, minor.

Access the trip trigger events

Why use trip triggers?

DriveKit's automatic start mode detects a trip and launches its recording immediately. This operating mode may not be appropriate for all use cases.

Your application may require other information or business logic before enabling the trip recording. For example, it may be appropriate to check that:

  • A connected device is near to the smartphone.

  • The trip recording is acceptable in a given time slot.

In this case, you may want to subscribe to the events that are indicative of the trip start but not necessarily launch the GPS sensor and the trip analysis.

This is why DriveKit allows you to subscribe to trigger events that indicate that a trip has probably started.

How does it work?

By default, this feature is disabled.

To enable this feature, DriveKit Trip Analysis should not be configured in automatic mode but in manual mode.

If DriveKit Trip Analysis is set to automatic mode, the trip will be recorded.

If DriveKit Trip Analysis is set to manual mode and you follow the instructions below, you will be able to listen for trip start trigger events but the trip analysis will not be started automatically.

To listen to trigger events that indicate a start of trip, even if the autostart is disabled, you can call the following method:

DriveKitTripAnalysis.shared.monitorPotentialTripStart = true

The potentialTripStart() method can return all StartMode values ; except MANUAL. Indeed, a trip manually started is considered as confirmed.

Get the arrival location of the last trip

This function returns the location of the end of the last trip recorded by the user.

The location is defined by GPS coordinates (latitude and longitude), along with the end date of the last trip and an accuracy indicator for the GPS reading.

You can use the end-of-trip coordinate for a variety of purposes, for example:

  • help the user find his vehicle

  • alert the customer that the user has reached a specific destination

  • create a region monitoring (also known as geofencing) to locate the vehicle

The last trip corresponds to the last trip recorded by the DriveKit SDK, regardless of the mode of transport used.

To retrieve the location at which the last recorded trip ended, use the following method:

func getLastTripLocation() -> DKTripLocation?

The method can return nil if the user:

  • is not authenticated,

  • or didn’t make a trip since the authentication,

  • or hasn’t made any valid trips.

DKTripLocation

Property/Method
Type
Description

date

Date

Date of the end of trip.

latitude

Double

Latitude of the end of the trip.

longitude

Double

Longitude of the end of the trip.

accuracyMeter

Double

GPS data accuracy value in meters.

func getAccuracyLevel()

DKCoordinateAccuracy

GPS data accuracy level. Possible values are described below.

DKCoordinateAccuracy

For ease of use, this function provides a position accuracy indicator with a 3-level scale.

Name
Description

good

The GPS accuracy is strictly below 10 meters.

fair

The GPS accuracy is between 10 and 30 meters.

poor

The GPS accuracy is strictly above 30 meters.

Permissions

Configure Capabilities

  1. Go to the Capabilities tab of your target settings.

  2. Turn on Background Modes and enable Location updates.

Configure permissions

As DriveKit requires a user's location and motion data, it is required to get permissions from the user.

When the application requests permission for background locations or motion activities, a message will be shown to the user. You must configure this message by changing the value for the following keys in Info.plist

  • NSLocationWhenInUseUsageDescription

  • NSLocationAlwaysAndWhenInUseUsageDescription

  • NSMotionUsageDescription

Ask for location permission

Since iOS 13 and DriveKit SDK 1.1.3, location permission must be requested in two steps because the "Always Allow" option is no longer available in standard iOS location permission alert. You must first request when in use authorization (locationManager.requestWhenInUseAuthorization()) and then ask the user to choose "Always Allow" option in the app settings and redirect user to the app settings page.

To ask for the location permission in a proper way, DriveKit provides the following function:

DKDiagnosisHelper.shared.requestPermission(.location)

Motion and Fitness permission

Therefore, if you install DriveKit in your application, a permission request will be displayed to ask for the user's consent.

If you do not want to use this feature and want to control the user experience related to the Motion and Fitness permission request, it can be disabled.

To deactivate the Motion and Fitness permission request, call:

DriveKitTripAnalysis.shared.activateActivityRecording(false)

Quick start

In this part, we will take you through the required basic steps to detect your first trips using DriveKit.

Prerequisites

To complete this quickstart, make sure that your development environment meets the following requirements:

  • Android Studio (latest version)

  • An Android 8.0+ device with Play Services

  • Your Android app must target API level 26 or higher.

Follow the steps described below in your app in order to quickly integrate the DriveKit SDK:

Set up your project

The DriveKit SDK is available on the DriveQuant Maven repository.

To access modules in the repository, add the following lines in your Gradle settings appropriate file, according to the structure of your app:

Add the TripAnalysis module to your project

To add the Trip Analysis module to your app, add the following line to your dependencies in your appropriate application build Gradle file:

By adding the TripAnalysis module, it will also add the DriveKit Core module and automatically initialize the DriveKit SDK.

Configure your backup app's rules

DriveKit periodically checks for changes related to the status of permissions, sensors, as well as user disconnection. This information is included in the diagnosis log file and shared with the DriveQuant platform.

To be more accurate and capture application uninstall events, you need to allow your app to backup data.

To do this, set the allowBackup attribute to true in your Manifest project app file as shown in the following example:

Set the API key

Once you've stored your API key in a secure way in your app, configure DriveKit by calling the following method:

Set a user id

Each driver must be identified with a unique identifier. Once you have this identifier and you are ready to analyze trips, configure DriveKit by calling the following method:

You can call setApiKey() and setUserId() methods anywhere in the code. DriveKit will save the value locally. If the app is killed and relaunched, DriveKit will be reconfigured automatically.

DriveKit SDK will not work until you set the API key and the userId.

Enable the autostart

The automatic mode detects vehicle movements and triggers the trip analysis without driver intervention even if the application is in background. The analysis is stopped automatically at the end of the trip.

This feature is recommended to avoid driver distraction and phone handling while driving. The automatic mode has been optimized to limit the battery drain.

By default, automatic trip detection is disabled, but you can enable it by calling the following method with the activate parameter to true:

Runtime permissions

DriveKit requires some runtime permissions to be granted by the user.

To display a simple and intuitive onboarding for the user to grant these runtime permissions, add the dependency for the PermissionsUtils graphical module in your appropriate application build Gradle file:

Then, call the following code in your project:

Congratulations! You now have an app that will automatically detects every trip you will make.

What's next?

Once your first trips are recorded, fine-tune the DriveKit SDK configuration to fit your needs:

Quick start

In this part, we will take you through the required basic steps to detect your first trips using DriveKit.

Prerequisites

To complete this quickstart, make sure that your development environment meets the following requirements:

  • Xcode (latest version)

  • An iPhone device, running on iOS 13.0+

Follow the steps described below in your app in order to quickly integrate the DriveKit SDK:

Set up your project

The DriveKit SDK is available on CocoaPods public repository.

To add TripAnalysis module, add the following line to your Podfile:

then run pod install

By adding the TripAnalysis module, it will also add the DriveKit Core module and automatically initialize the DriveKit SDK.

Configure Capabilities

  • Go to the Capabilities tab of your target settings.

  • Turn on Background Modes

  • Enable Location updates (to be able to receive location updates in the background)

Configure permissions

As DriveKit requires a user's location and motion data, it is required to get permissions from the user.

When the application requests permission for background locations or motion activities, usage description messages will be shown to the user. Since DriveKit imports CoreBluetooth framework, we strongly recommend you to also include Bluetooth usage description message. You must configure these messages by adding the following lines in the Info.plist file:

Configure background task ID

In the case you already have a background refresh task, as iOS allow only one scheduled background fetch task, you will need to reuse your existing BGAppRefreshTask to call the following function:

In this case, don’t add the new “Permitted background task scheduler identifier” to your Info.plist.

Set the API key

Once you've stored your API key in a secure way in your app, configure DriveKit by calling the following method:

Identify the user

Each driver must be identified with a unique identifier. Once you have this identifier and you are ready to analyze trips, configure DriveKit by calling the following method:

You can call setApiKey and setUserId methods anywhere in the code. DriveKit will save the value locally. If the app is killed and relaunched, DriveKit will be reconfigured automatically.

DriveKit SDK will not work until you set the API key and the userId.

Enable the autostart

The automatic mode detects vehicle movements and triggers the trip analysis without driver intervention while the application is in background. The analysis is stopped automatically at the end of the trip.

This feature is recommended to avoid driver distraction and phone handling while driving. The automatic mode has been optimised to limit the battery drain.

By default, automatic trip detection is disabled, but you can enable it by calling the following method with the enable parameter to true:

Asking for permissions

To display a simple and intuitive onboarding for the user to grant these runtime permissions, add the dependency for the PermissionUtils graphical module in your Podfile:

then run pod install

The method below helps you to configure the required permission requests and the order in which they are displayed. You will be notified when the requested permissions are successfully granted:

Congratulations! You now have an app that will automatically detect every trip you will make.

What's next?

Once your first trips are recorded, fine-tune the DriveKit SDK configuration to fit your needs:

Android 14 Migration guide

1 - Check major changes

It is necessary to read this documentation before modifying any code in your project.

You must consider the two main categories of behaviours changes related to Android 14:

2 - Targeting Android 14 in your project

To make your app fully compatible with Android 14, update the targetSdkVersion and compileSdkVersion to 34 in your project app.

3 - Apply changes ("All Apps" and "Apps targeting Android 14")

It's now time to update your code once the previous steps are taken into account.

DriveQuant recommends to specifically pay attention about these topics that can lead to a runtime crash:

4 - Update the DriveKit SDK

After you have checked that your project is working properly and updated the targetSdkVersion and compileSdkVersion, you need to update the DriveKit SDK.

  • DriveKit internal modules that support Android 14 are versions 1.35 and above.

  • DriveKit UI modules that support Android 14 are versions 1.39 and above.

The latest DriveKit versions are listed in the changelog:

5 - Tests 🚗

If you experience any problems with DriveKit, please contact us.

Crash Detection

Principle

Crash detection features, included into the DriveKit Trip Analysis component, is able to collect and analyse smartphone sensors data to automatically detect when a car accident occurs.

DriveKit Trip Analysis analyzes signals from the GPS sensor and also from the motion sensors (accelerometer, gyrometer and magnetometer).

This feature is enabled if the following conditions are fulfilled:

  • Your API key has the access rights to use this service;

  • You have enabled the feature by following the instructions described in this section;

  • A trip has been detected and is being analysed.

  • The smartphone's sensors are functional.

  • The SDK is able to check the status of the required sensors.

The crash detection steps are:

  1. A trip is detected automatically or started manually and the trip recording starts.

  2. The crash feature detects a potential collision based on motion sensors.

  3. The GPS and motion data are pushed to the backend analysis services in charge of the signal processing and crash confirmation.

  4. The SDK receives a crash analysis service response with a status.

  5. If the crash is confirmed, the Trip analysis component can display a survey to ask the driver whether he needs assistance. This is an optional feature.

Enable crash detection

If the crash detection configuration is enabled for your company, your API key carries out the feature access and the crash detection will be enabled accordingly.

However, you can deactivate and reactivate the function if necessary using a dedicated setting.

A method is available in DriveKitTripAnalysis to enable or disable the feature:

Verify that the feature is available

It is possible to check if the crash detection is available for your configuration by checking the following property:

This property returns true if:

  • the required smartphone sensors are available and up and running;

  • your API key is allowed to use the feature;

If this property returns false, DriveKit will not start crash detection feature even if it has been previously activated with activateCrashDetection().

Configure crash detection feedback

Trip Analysis offers a mechanism to ask the user for feedback when an accident is confirmed by the crash analysis service. Crash confirmation can be used to trigger a notification or display a screen which asks the driver to confirm the accident and whether assistance is required.

To disable the crash detection feedback, call the following method:

Listening to Crash events

TripListener protocol provides two callbacks for crash events:

To receive these callbacks, the smartphone must be connected to a mobile network and the accident detection feature must be enabled for your organisation's API key.

TripListener

The TripListener protocol provides useful information and events about trips analyzed by DriveKit.

For example, you can be informed when a trip analysis has started, finished, canceled, when a crash is detected, etc.

Add a TripListener

You can remove a specific listener using the following method:

To remove all TripListeners objects:

If you remove all your trip listeners or forget to add one, your app will not receive any feedback from the trip analysis module. It will not prevent the analysis from working but your code will not be able to execute its own logic (UI updates, notification, etc.).

Do not forget to remove your TripListener objects when you don't need it anymore.

TripListener interface includes several methods to implement:

End of trip notification: Depending on the trip analysis service's response in the tripFinished() callback, we recommend that you specify the notification content if you decide to display a user feedback:

  • For a vehicle trip, you can display a message such as: Your trip has been analyzed.

  • For a trip by rail it is better to display the following message: Your trip was made by train.

Get the trip response status (Deprecated)

This method has been deprecated and will be removed at the end of 2025.

Once the DriveQuant servers has analyzed a trip, the tripFinished() callback is triggered with the data in the PostGenericResponse object.

It can be useful to check the trip response status in order to check for example if the trip is valid or not with detailed information.

To do this, call the following method:

If a trip is running when automatic trip detection is disable, the trip will not be canceled. If you want to cancel the trip, you should also call method.

If a vehicle stops longer than the , the trip will be stopped automatically.

A detailed description of vehicle parameter is available .

⚠️ It is different from the startDate property returned in the object.

The which triggered the trip analysis.

💡 You have to call the method to in your workflow.

This feature allows you to share to the server the location of a driver during all his trips. It is different from the feature where the user chooses to share his trips for a certain duration, thanks to a link showing his current trip on a map.

Once the feature is enabled, events will be available in the potentialTripStart() callback.

By default, the SDK incorporates the permission request to access Motion and Fitness. This allows for improved transportation mode recognition through the use of based on motion properties.

You can also clone the following , configure the required credentials then simply run the quickstart app!

Replace $drivekit_versionwith the latest release version of DriveKit on the page.

In some cases you may want to manually initialize the SDK. To do this you have to disable the automatic initialization. Learn more in the part.

By enabling backup, only DriveKit data will be backed up. If you want to back up data of your application (such as your SharedPreferences), you must declare your own rules in your Manifest (see ).

All other diagnosis events (described ) will be provided regardless of the allowBackup configuration.

In case of Manifest merging issue with DriveKit, please refer to the page.

We recommend never using an email address or phone number to define the unique user ID. It is recommended that you set up a unique, universal and anonymous user ID. For example, you can generate a globally unique identifier () for each of your users.

Replace $drivekitui_version with the latest release version of graphical modules on the page.

Configure the and modules with advanced settings. For example, ,, activate the , etc.

Display trip-related data: provide a trip list, a timeline of driver’s score, present the user's driving habits, etc. by integrating the module.

Associate each trip to a vehicle that you can configure with the module.

Improve user retention by organizing , display with the community, show which the driver earned, etc.

A DriveKit API key. If you don't have an API key, please contact .

You can also clone the following , configure the required credentials then simply run the quickstart app!

In some cases you may want to manually initialize the SDK. To do this you have to disable the automatic initialization. Learn more in the part.

Enable Background fetch (to periodically check for changes related to the status of authorizations, sensors, as well as user disconnection. See more info )

These values can be localized (see our for example).

DriveKit periodically checks for changes related to the status of authorizations, sensors as well as user disconnection. This information is included in the diagnostic log file and shared with the DriveQuant platform. To be more accurate, this feature needs to have and a background task id declared in your Info.plist file. You must add the following line in Info.plist file:

We recommend never using an email address or phone number to define the unique user ID. It is recommended that you set up a unique, universal and anonymous user ID. For example, you can generate a globally unique identifier () for each of your users.

Configure the and modules with advanced settings. For example, , activate the , etc.

Display trip-related data: provide a trip list, a timeline of driver’s score, present the user's driving habits, etc. by integrating the module.

Associate each trip to a vehicle that you can configure with the module.

Improve user retention by organizing , display with the community, show which the driver earned, etc.

Android offers a clear and exhaustive listing the new features and changes related to Android 14.

The last part is to ensure that the app is working as expected. The best way to do this is to compare your app's behaviour with the and/or the ; which already support Android 14.

The crash detection comes with an optional user interface to display an alert to the driver. This is described in the section.

To use this function, you simply need to enable the interface with the following method and a object:

crashDetected(crashInfo:), called when a crash event is detected

crashFeedbackSent(crashInfo:, feedbackType: , severity:), called when crash feedback is enabled and a confirmed crash is detected. This callback will contain crash information and the feedback from the user.

The trip recording lifecycle is exhaustively described in part.

Method
Description

The callback method tripFinished(post: PostGeneric, response: PostGenericResponse) is replaced by tripFinished(responseStatus: TripResponseStatus) which directly provides the useful information (see ).

The model is described in the References part.

TripListener
activity recognition
cancelTrip
timeout configured
trip sharing with a link
dependencyResolutionManagement {
    repositories {
        (…)
        maven {
            url = uri("https://maven.drivequant.com/repository/android-sdk/")
        }
    }
}
dependencyResolutionManagement {
    repositories {
        (…)
        maven {
            url "https://maven.drivequant.com/repository/android-sdk/"
        }
    }
}
allprojects {
    repositories {
        (…)
        maven {
            url "https://maven.drivequant.com/repository/android-sdk/"
        }
    }
}
dependencies {
    implementation("com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version")
}
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version'
}
AndroidManifest.xml
<manifest ... >
    ...
    <application android:allowBackup="true" ... >
        ...
    </application>
</manifest>
fun setApiKey(key: String)
fun setUserId(userId: String)
fun activateAutoStart(activate: Boolean)
dependencies {
    implementation("com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version")
    implementation("com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version")
}
dependencies {
    implementation "com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version"
    implementation "com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version"
}
PermissionsUtilsUI.showPermissionViews(context, object: PermissionViewListener {
    override fun onFinish() {
        // Code called when requested permissions are properly granted.
    }
})
target 'DriveKit Quickstart' do
   pod 'DriveKitTripAnalysis'
end
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>To enable automatic trip detection and driving analysis without having to manipulate your phone, select the option "Always allow". Good road...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>To automatically detect and analyze your trips, the application needs access to your position at all times.</string>
<key>NSMotionUsageDescription</key>
<string>This application needs to use motion data to detect transportation mode</string>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>The application needs to use bluetooth in order to retrieve beacon battery level</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>The application needs to use bluetooth in order to retrieve beacon battery level</string>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
	<string>com.drivequant.diagnosis.app.refresh</string>
</array>
DKSDKDiagnosis.shared.enqueueDiagnosisOperation(source: .backgroundFetch) { success in
    //task.setTaskCompleted(success: success)
}
func setApiKey(key: String)
func setUserId(userId: String)
func activateAutoStart(enable: Bool)
target 'DriveKit Quickstart' do
   pod 'DriveKitTripAnalysis'
   pod 'DriveKitPermissionsUtilsUI'
end
DriveKitPermissionsUtilsUI.shared.showPermissionViews([.location, .activity], parentViewController: self) {
    // Code called when requested permissions are properly granted.
}
func activateCrashDetection(_ enable: Bool)
var isCrashDetectionAvailable: Bool
func enableCrashFeedback(config: DKCrashFeedbackConfig)
func disableCrashFeedback()
func addTripListener(_ tripListener: TripListener)
func removeTripListener(_ tripListener: TripListener)
func removeAllTripListeners()
func getTripResponseStatus(_ tripResponse: PostGenericResponse) -> TripResponseStatus

Android

Troubleshooting

This page can be helpful if you encounter some build issues with DriveKit SDK in your app.

dataExtractionRules property merge issue

If an error message appeared when building your app is something like:

Error: Attribute application@dataExtractionRules value=(@xml/data_extraction_rules) from AndroidManifest.xml:12:9-65 is also present at [com.drivequant.drivekit:drivekit-core:x.x.x] AndroidManifest.xml:13:9-56 value=(@xml/backup_rules). Suggestion: add 'tools:replace="android:dataExtractionRules"' to element at AndroidManifest.xml:9:5-31:19 to override.

It's a backup rules merging issue with DriveKit SDK rules and your app and/or another external library you use.

To resolve this, update your AndroidManifest.xml file:

<application
        android:dataExtractionRules="@xml/merged_data_extraction_rules"
        tools:replace="android:dataExtractionRules"
/>        

Then find the related backup rules of your app or the external library and create the file merged_data_extraction_rules.xml in the src/main/res/xmlfolder:

<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
    <!-- Exclude rules of your app and/or the external libraries  -->
    <cloud-backup>
        <exclude domain="sharedpref" path="DriveKitPreferences.xml" />
        <exclude domain="sharedpref" path="DriveKitEncryptedPreferences.xml" />
        <exclude domain="sharedpref" path="DriveKitBackupPrefs.xml" />
        <include domain="sharedpref" path="DriveKitBackup.xml" />
    </cloud-backup>
    <device-transfer>
        <exclude domain="sharedpref" path="DriveKitPreferences.xml" />
        <exclude domain="sharedpref" path="DriveKitEncryptedPreferences.xml" />
        <exclude domain="sharedpref" path="DriveKitBackupPrefs.xml" />
        <include domain="sharedpref" path="DriveKitBackup.xml" />
    </device-transfer>
</data-extraction-rules>

fullBackupContent property merge issue

If an error message appeared when building your app is something like:

Error: Attribute application@fullBackupContent value=(@xml/app_backup_exclusion) from [com.anotherSdk.library:xxx:x.y.z] AndroidManifest.xml:22:18-76 is also present at [com.drivequant.drivekit:drivekit-core:x.x.x] AndroidManifest.xml:11:9-69 value=(@xml/backup_rules_pre_android_12). Suggestion: add 'tools:replace="android:fullBackupContent"' to element at AndroidManifest.xml:42:3-72:17 to override.

It's a backup rules merging issue with DriveKit SDK rules and your app and/or another external library you use.

To resolve this, update your AndroidManifest.xml file:

<application
        android:fullBackupContent=""
        tools:replace="android:fullBackupContent" 
        (…)
/>

Then find the related backup rules of your app or the external library and create the file merged_backup_rules.xml in the src/main/res/xmlfolder:

merged_backup_rules.xml
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
	<!-- Exclude rules of your app and/or the external libraries  -->

	<exclude domain="sharedpref" path="DriveKitPreferences.xml" />
	<exclude domain="sharedpref" path="DriveKitEncryptedPreferences.xml" />
	<exclude domain="sharedpref" path="DriveKitBackupPrefs.xml" />
	<include domain="sharedpref" path="DriveKitBackup.xml" />
</data-extraction-rules>

If you have both dataExtractionRules and fullBackupContent merge issues, you have to declare the two attrbutes as follows:

<application
        android:dataExtractionRules="@xml/merged_data_extraction_rules"
        android:fullBackupContent="@xml/merged_backup_rules"
        tools:replace="android:dataExtractionRules, android:fullBackupContent"
        (…)
/>

BackupAgent merge issue

If an error message appeared when building your app looks like:

Manifest merger failed : Attribute application@backupAgent value=(com.yourApp.yourClass) from AndroidManifest.xml:9:9-47
	is also present at [:Core] AndroidManifest.xml:11:9-86 value=(com.drivequant.drivekit.core.backup.DriveKitBackupAgent).
	Suggestion: add 'tools:replace="android:backupAgent"' to <application> element at AndroidManifest.xml:7:5-42:19 to override.

It's because DriveKit SDK is using the BackupAgent to restore some user information when the user has reinstalled the app.

DriveKit is providing two ways to handle the error:

Way 1 - Inherit from DriveKitBackupAgent

The easiest way is to make your BackupAgent class inherits our DriveKitBackupAgent class.

Way 2 - Call DriveKit backup methods

If you cannot inherit from DriveKitBackupAgent class, e.g. when you already inherits from another class, you can still:

  1. Add tools:replace="android:backupAgent in your Manifest as suggested in the error message.

  2. Call DriveKitBackupAgent.onCreate(BackupAgentHelper) in your overriden onCreate() method

  3. Call DriveKitBackupAgent.onRestoreFinished(BackupAgentHelper) in your overriden onRestoreFinished() method

repository
changelog
Advanced configurations
https://developer.android.com/identity/data/autobackup#IncludingFiles
here
Troubleshooting
GUID
changelog
Driver Data
Vehicle
us
repository
Advanced configurations
English file
GUID
Core
TripAnalysis
alert the user once a trip has been analyzed by the DriveQuant servers by displaying a notification
crash detection
Driver Data
Vehicle
documentation
Behavior changes: all apps
Behavior changes: Apps targeting Android 14 or higher
Foreground services type are required
Restrictions to implicit and pending intents
For internal modules
For UI modules
DriveQuant's app
DriveKit Demo App
user interface
DKCrashFeedbackConfig
DKCrashInfo
DKCrashInfo
DKCrashFeedbackType
DKCrashFeedbackSeverity
Trip recording lifecycle
retrieve an existing link
here
background fetch capability

tripRecordingStarted(state: DKTripRecordingStartedState)

Immediately called when a trip recording starts.

This callback is triggered:

  • after automatic trip detection.

tripRecordingConfirmed(state: DKTripRecordingConfirmedState)

tripRecordingCanceled(state: DKTripRecordingCanceledState)

Called when a trip recording is canceled. DKTripRecordingCanceledState indicates which event has canceled the trip.

tripRecordingFinished(state: DKTripRecordingFinishedState)

tripFinished(responseStatus: TripResponseStatus)

This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.

tripPoint(tripPoint: TripPoint)

tripSavedForRepost()

Called if at the end of the trip, the trip couldn't be sent to DriveQuant's server for the analysis, for example when the smartphone has no network. The trip is saved locally on the SDK and will automatically be sent later.

beaconDetected()

Called when a beacon sets in the SDK is detected.

significantLocationChangeDetected()

Called when a user significant location change is detected.

sdkStateChanged(state: State)

crashDetected(crashInfo: DKCrashInfo)

crashFeedbackSent(crashInfo: DKCrashInfo, feedbackType: DKCrashFeedbackType, severity: DKCrashFeedbackSeverity)

tripFinished(post: PostGeneric, response: PostGenericResponse)

This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.

Runtime permissions

Location Permission

It is required to ask the user for location permission. Find below an example of how to ask location permission:

fun checkLocationPermission(requestCode: Int) {
    val permissionFineLocationApproved = ActivityCompat.checkSelfPermission(this,
        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED

    if (permissionFineLocationApproved) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val backgroundLocationPermissionApproved = ActivityCompat.checkSelfPermission(
                this, Manifest.permission.ACCESS_BACKGROUND_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
            if (!backgroundLocationPermissionApproved) {
                ActivityCompat.requestPermissions(this,
                    arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                    requestCode)
            }
        }
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ActivityCompat.requestPermissions(this,
                arrayOf(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                requestCode)
        } else {
            ActivityCompat.requestPermissions(this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                requestCode)
        }
    }
}
private void checkLocationPermission(int requestCode) {
        boolean permissionFineLocationApproved = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;

        if (permissionFineLocationApproved) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                boolean backgroundLocationPermissionApproved = ActivityCompat.checkSelfPermission(
                        this, Manifest.permission.ACCESS_BACKGROUND_LOCATION
                ) == PackageManager.PERMISSION_GRANTED;
                if (!backgroundLocationPermissionApproved) {
                    ActivityCompat.requestPermissions(this,
                            new String[] { Manifest.permission.ACCESS_BACKGROUND_LOCATION },
                            requestCode);
                }
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                ActivityCompat.requestPermissions(this,
                        new String[] {
                                Manifest.permission.ACCESS_FINE_LOCATION,
                                Manifest.permission.ACCESS_BACKGROUND_LOCATION },
                        requestCode);
            } else {
                ActivityCompat.requestPermissions(this,
                        new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                        requestCode);
            }
        }
    }

If location permission is not granted by the user, Trip Analysis SDK will not work.

Activity Recognition Permission

For device running Android 10 and above, it's required to ask the user for activity recognition permission. Find below an example of how to ask the permission:

fun checkActivityRecognitionPermission(requestCode: Int) {
    var isActivityRecognitionAuthorize = true
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        isActivityRecognitionAuthorize = ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED
    } else {
        // call DriveKitTripAnalysis.activateAutoStart(true)
    }
    if (!isActivityRecognitionAuthorize && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACTIVITY_RECOGNITION)) {
            // Display a message to explain why the permission is necessary
        } else {
            ActivityCompat.requestPermissions(this,
                arrayOf(Manifest.permission.ACTIVITY_RECOGNITION),
                requestCode)
        }
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    // call DriveKitTripAnalysis.activateAutoStart(true)
}
private void checkActivityRecognitionPermission(int requestCode) {
    boolean isActivityRecognitionAuthorize = true;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        isActivityRecognitionAuthorize = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED;
    } else {
        // call DriveKitTripAnalysis.INSTANCE.activateAutoStart(true)
    }
    if (!isActivityRecognitionAuthorize && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACTIVITY_RECOGNITION)) {
            // Display a message to explain why the permission is necessary
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[] { Manifest.permission.ACTIVITY_RECOGNITION },
                    requestCode);
        }
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // call DriveKitTripAnalysis.INSTANCE.activateAutoStart(true)
}

If activity recognition permission is not granted by the user, Trip Analysis component will not work.

Battery optimization

It is required to ask the user to disable battery optimization for your app. Without battery optimization disabled, Trip Analysis SDK will not work properly.

Call the following code after explaining to the user why disabling battery optimization is required:

fun checkBatteryOptimization() {
    val packageName = this.packageName
    val pm = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
    if (!pm.isIgnoringBatteryOptimizations(packageName)) {
        val intent = Intent()
        intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
        intent.data = Uri.parse("package:$packageName")
        this.startActivity(intent)
    }
}
void checkBatteryOptimization() {
    Intent intent = new Intent();
    String packageName = getPackageName();
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    if (pm != null && !pm.isIgnoringBatteryOptimizations(packageName)) {
        intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));
        startActivity(intent);
    }
}

If battery optimization is enabled, trip recording will not work.

Nearby Devices Permission

fun checkNearbyDevicesPermission(activity: Activity, requestCode : Int) {
    val isNearbyDevicesPermissionAuthorized = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        ContextCompat.checkSelfPermission(
            activity, Manifest.permission.BLUETOOTH_SCAN
        ) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(
            activity, Manifest.permission.BLUETOOTH_CONNECT
        ) == PackageManager.PERMISSION_GRANTED
    } else {
        true
    }

    if (!isNearbyDevicesPermissionAuthorized && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        val shouldShowRationaleScan = shouldShowRequestPermissionRationale(activity, Manifest.permission.BLUETOOTH_SCAN)
        val shouldShowRationaleConnect = shouldShowRequestPermissionRationale(activity, Manifest.permission.BLUETOOTH_CONNECT)
        if (!shouldShowRationaleScan || !shouldShowRationaleConnect) {
            // Display a message to explain why the permission is necessary 
        } else {
            requestPermissions(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT), requestCode)
        }        
    }
}
public void checkNearbyDevicesPermission(Activity activity, int requestCode) {
    boolean isNearbyDevicesPermissionAuthorized;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        isNearbyDevicesPermissionAuthorized = ContextCompat.checkSelfPermission(
                activity, Manifest.permission.BLUETOOTH_SCAN
        ) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(
                activity, Manifest.permission.BLUETOOTH_CONNECT
        ) == PackageManager.PERMISSION_GRANTED;
    }  else {
        isNearbyDevicesPermissionAuthorized = true;
    }
    
    if (!isNearbyDevicesPermissionAuthorized && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        final boolean shouldShowRationaleScan = shouldShowRequestPermissionRationale(activity, Manifest.permission.BLUETOOTH_SCAN);
        final boolean shouldShowRationaleConnect = shouldShowRequestPermissionRationale(activity, Manifest.permission.BLUETOOTH_CONNECT);
        if (!shouldShowRationaleScan || !shouldShowRationaleConnect) {
            // Display a message to explain why the permission is necessary
        } else {
            requestPermissions(activity, new String[] { Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT }, requestCode);
        }
    }
}

If Nearby Devices permission is not granted by the user, Trip Analysis component won't work correctly.

Notification Runtime Permission

Find below an example of how to ask the Notification permission:

First, declare the permission in your Manifest app file:

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

Then request the permission on your UI:

fun checkNotificationPermission(activity: Activity, requestCode: Int) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        val isNotificationPermissionAuthorized = ContextCompat.checkSelfPermission(activity,
            Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED

        if (!isNotificationPermissionAuthorized) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.POST_NOTIFICATIONS)) {
                // Display a message to explain why the user need to grant the permission
            } else {
                ActivityCompat.requestPermissions(activity,
                    arrayOf(Manifest.permission.POST_NOTIFICATIONS),
                    requestCode)
            }
        }
    }
}
public void checkNotificationPermission(Activity activity, int requestCode) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        boolean isNotificationPermissionAuthorized = ContextCompat.checkSelfPermission(activity, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED;
        if (!isNotificationPermissionAuthorized) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.POST_NOTIFICATIONS)) {
                // Display a message to explain why the user need to grant the permission
            } else {
                ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.POST_NOTIFICATIONS }, requestCode);
            }
        }
    }
}

Full-screen intent permission

If the permission is not granted, the user will not receive full-screen notifications when the smartphone is locked, but instead an expanded heads-up notification on lockscreen. Find below an example of how to ask the full-screen intent permission:

First, declare the permission in your Manifest app file:

<manifest ...>
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
    <application ...>
        ...
    </application>
</manifest>

Then request the permission on your UI:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    DiagnosisHelper.requestFullScreenPermission(activity)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
    DiagnosisHelper.INSTANCE.requestFullScreenPermission(activity);
}

Google Play Services

Trip Analysis component requires Google Play Services Location 21.0.1 or above.

You can check if Play Services are available on the device with the following code:

fun checkGooglePlayServices() {
    val apiAvailability = GoogleApiAvailability.getInstance()
    val resultCode = apiAvailability.isGooglePlayServicesAvailable(this)
    if (resultCode != ConnectionResult.SUCCESS) {
        if (apiAvailability.isUserResolvableError(resultCode)) {
            apiAvailability.getErrorDialog(this, resultCode, 9000).show()
        }
    }
}

Bluetooth usage

Principle

Bluetooth wireless technology is a common solution in modern vehicles. Most drivers know that by pairing their Bluetooth smartphone with their car stereo receiver, they will be able to make hands-free calls or to stream their music to the car audio system.

Once the smartphone's paired with the vehicle, it automatically connects to it if the vehicle is started.

Trip Analysis SDK is capable of detecting this event to start a trip analysis.

A Bluetooth device is identified by a unique MAC address and an optional name. It can be detected by the SDK and used to trigger the trip analysis.

The use of the vehicle Bluetooth detection is a simple and cost-effective solution to identify the trips made with your vehicle.

Configure a Bluetooth device

You can retrieve all Bluetooth devices paired to the smartphone by calling the following method:

let devices = DriveKitTripAnalysis.shared.getAvailableBluetoothDevices()

Bluetooth device will be seen only if the iPhone is connected to the vehicle bluetooth when this functions is called.

You can add Bluetooth devices to Trip Analysis SDK by calling the following method:

DriveKitTripAnalysis.shared.setBluetoothDevices(bluetoothDevices: [BluetoothData])

If you want to remove Bluetooth devices from SDK configuration, just call the method with an empty array.

Bluetooth device required

Pairing the vehicle's Bluetooth system improves the trip detection and analysis. With this feature you can decide to enable or disable the trip recording when the Bluetooth device is not connected. There are two possibilities:

  1. the trip can be recorded even if the smartphone is not connected to the Bluetooth device.

  2. the trip recording will be cancelled if the smartphone is not connected to the Bluetooth device.

This choice depends on your use case. In general, if you only want to record trips made with the vehicle equipped with the paired Bluetooth system, you must prefer the second choice.

To avoid trip recording when the Bluetooth device is not connected, call the following method:

DriveKitTripAnalysis.shared.setBluetoothDeviceRequired(true)

To enable trip recording regardless of the state of the Bluetooth system (connected or not connected to the smartphone), call the following method:

DriveKitTripAnalysis.shared.setBluetoothDeviceRequired(false)

Beacon usage

Configure beacons

The automatic trip detection feature is compliant with iBeacon Bluetooth beacons. A beacon is a Bluetooth low energy (BLE) device that broadcasts a universally unique identifier. This signal can be detected by the SDK and used to trigger the trip analysis.

In addition, the beacon is a smart and cost-effective solution for identifying the vehicle in which the driver is travelling.

You can add beacon identifiers to Trip Analysis SDK by calling the following method:

DriveKitTripAnalysis.shared.setBeacons(beacons: [BeaconData])

Beacons can have 3 configurations:

  • Only proximityUuid: All beacons with this proximityUuid value can start a trip (independently from major and minor value).

    • BeaconData(proximityUuid: String)

  • ProximityUuid + major: All beacons with this proximityUuid and major values can start a trip (independently from minor value).

    • BeaconData(proximityUuid: String, major: Int)

  • ProximityUuid + major + minor: All beacons with this proximityUuid, major and minor values can start a trip.

    • BeaconData(proximityUuid: String, major: Int, minor: Int)

Since iOS13, iOS beacon functions have some limitations, therefore all configured beacons must have the same proximity UUID.

If you want to remove beacons from SDK configuration, just call the method with an empty array.

On iOS, there is a limitation of 20 regions (including beacons) that can be monitored. Consequently, make sure that you limit to the minimum the number of beacons configured in the SDK.

Beacon required

To avoid the recording of unwanted trips (trips performed outside the vehicle where the beacon is placed), it is possible to automatically cancel the trip if the beacon is not "seen" several times during the trip. Generally, a trip will be cancelled in less than 6 minutes if the beacon is not in the vehicle.

By default, this setting is disabled, but you can enable it by calling the following method:

DriveKitTripAnalysis.shared.setBeaconRequired(required: true)

To disable this settings, call the same method with the parameter set to false

DriveKitTripAnalysis.shared.setBeaconRequired(required: false)

Filter the beacon trigger to start trip recording

In very rare cases, it may be useful to avoid trip detection using the beacon but still need to validate the trip recording only if the beacon is near the smartphone during the trip.

In this case, the beacon is used in trip validation mode but not in trip detection mode.

If this advanced configuration is not used correctly, it may result in poor trip detection performance.

Please never use this feature without contacting DriveQuant to explain your use case and ensure that this particular mode is mandatory.

How does it work ?

By default, if you have configured a beacon, its detection by the SDK will start a trip analysis.

In very rare cases (e.g. beacon in a vehicle and parked in close proximity to a living area), it might be useful to avoid the SDK to start a trip when a beacon is detected to reduce smartphone battery consumption.

Please note that beacon scans checks are always performed during the trip analysis, even if the configuration is called.

To disable the ability to start a trip analysis when a beacon is detected by DriveKit, you can call the following method:

DriveKitTripAnalysis.shared.allowBeaconTripStart = false

This feature has no effect if the automatic trip detection mode is disabled.

Beacon battery level

For this functionality to work properly, the user must allow access to Bluetooth and you have to configure your project to allow background access to Bluetooth as described below.

  • In your target, in the "Signing & Capabilities" tab, you need to check the "Uses Bluetooth LE accessory" box in "Background Modes":

  • Ask the user for Bluetooth access authorization if it is not already granted. To do this, you can call this method:

DKDiagnosisHelper.shared.requestPermission(.bluetooth)

The App Store review team may need to know why the "Uses Bluetooth LE accessory" background mode is needed for your app. To prevent your app from being temporary rejected by Apple during the review process, you should add a note like this in "App Review Information" > "Notes" section of App Store Connect:

  • Why is "bluetooth-central" UIBackgroundModes needed?

    If the user has configured a vehicle with "Beacon" autostart mode and a trip analysis has been launched thanks to the detection of this beacon, we scan Bluetooth LE peripherals to retrieve the battery level of the beacon and send it to our backend to eventually warn the user to change his beacon if the battery level is low. Since the trip analysis is usually done in background, we need this UIBackgroundModes.

References (iOS)

TripResponseStatus

TripResponseStatus indicates if the analyzed trip by the DriveQuant servers is valid or not (see status property) and provides information on the analysis result:

TripResponseInfo

TripResponseError

DKTrip

DKDeclaredTransportationMode

The user has the possibility to declare the transportation mode that was used during a trip to confirm the one detected or to change it, and to declare whether the trip was made as a passenger or as the driver.

Here is the description of the corresponding object:

DKTripRecordingStartedState

DKTripRecordingConfirmedState

DKTripRecordingCanceledState

DKTripRecordingFinishedState

StartMode

StartMode indicates how the trip is started. It is an enum with the following values:

DKTripCancelationReason

TripPoint

TripPoint is an object that contains data for each location registered by the SDK.

TripVehicle

TripVehicle is an object that contains vehicle detailed characteristics.

BeaconData

BeaconData is an object that contains beacon characteristics.

BluetoothData

BluetoothData is an object that contains the Bluetooth device characteristics.

DKCrashInfo

Crash information object have the following structure:

with the following enumeration for crash status

DKCrashFeedbackConfig

DKCrashFeedbackConfig is an object used to configure the Crash Detection feedback feature.

DKCrashFeedbackNotification

DKCrashAlert

CrashFeedbackType

CrashFeedbackSeverity

CancelTrip (Deprecated)

CancelTrip indicates how the trip was cancelled. It is an enum with the following values:

Trip management

Configure the trip notification content

TripNotification is an object that contains the configuration of the foreground notification displayed during a trip recording.

To configure the trip notification in your app, call the following code:

The cancelIconId and cancel parameters must be set if the enableCancel parameter is set to true.

Trip autostart

By default, the trip autostart feature is disabled.

To enable automatic trip detection, call the following method with parameter activate set to true.

Manually start a trip

You can start a trip by calling the following method:

If a trip is already started, calling this method will have no effect.

Stop a trip

You can stop a trip by calling the following method. The trip will be stopped instantly:

If a vehicle stops longer than the configured, the trip will be stopped automatically.

If no trip is running, calling this method will have no effect.

Cancel a trip

If you want to cancel a trip, you can call this method:

Vehicle

To obtain a more precise analysis on driving behavior, it's recommended to configure the vehicle used by the driver. You can do this by calling the following method:

If no vehicle is configured a default vehicle will be configured with following parameters:

  • carTypeIndex = 1

  • carEngineIndex = 1

  • carPower = 150

  • carMass = 1400

  • carGearboxIndex = 2

  • carConsumption = 4.5

  • engineDisplacement = 1200

  • frontTireSize = "205/55/16"

  • rearTireSize = "205/55/16"

  • length = 4.5

  • width = 1.8

  • height = 1.45

  • engineCylinderNb = 4

  • driveWheels = 0

SDK recorder state

Two methods are available to determine SDK state.

This method returns false if the SDK is in INACTIVE state, and no trip is currently running.

If you want a more detailed state of the SDK, you can call the following method:

This method returns the state of the SDK:

  • INACTIVE: No trip is running.

  • STARTING: The auto start mode detects a movement of the user and checks if it's a trip in vehicle.

  • RUNNING: The trip has been confirmed by the speed of the movement.

  • SENDING: The trip is finished and is being sent to DriveQuant's server. When the SDK has the response from the server, the state becomes INACTIVE waiting for the next trip.

Get information about the current trip

When a trip recording is starting, you may need some information about it, like the StartMode which triggers the trip recording, a local unique identifier of the trip that has not yet been analyzed by the DriveQuant’s servers, etc.

  • The local unique identifier generated by the SDK (localTripId) is different from the unique trip identifier generated after data analysis (itinId).

  • A local trip identifier generated by the SDK (localTripId) is linked to a single unique trip identifier (itinId).

  • If the trip is cancelled locally, there will be no trip analysis and therefore no unique trip identifier (itinId) linked to the unique local identifier (localTripId).

To retrieve information about the current trip, use the following method:

The method can return null if there is no trip currently recording.

DKTripInfo

Manual trip repost

Trip Analysis SDK have a repost mechanism. In most cases, when a trip is finished, it is sent to DriveQuant's server for analysis. Once it's done, the result of the analysis is sent back to the SDK.

In some case, the trip can't be sent to DriveQuant's server (for example, when there is no network). In this case, the SDK will save the trip data locally to send it later.

An automatic retry will be attempted later when you are connected to network.

You can manually check whether trips are to be sent to the DriveQuant servers using the following method:

If no trip is running or if the trip has been sent to the server and is currently being analyzed, calling this method will have no effect.

After a trip cancel, the automatic start function will not restart a new trip recording if the user has not walked. Without this mechanism, if the user cancels a trip recording because he is on public transport and not driving, the trip will restart immediately.

Custom stop timeout

A trip being analyzed is automatically terminated after a period of inactivity (which begins when the vehicle has stopped). The SDK allows to set the end-of-trip duration.

By default, the trip analysis is stopped after 240 seconds. This value can be tuned according to your need and you can choose any integer values between 120 and 480 seconds by calling the following method:

If a value greater than 480 is set, the value will be forced to 480.

If a value lower than 120 is set, the value will be forced to 120.

Manage the location sharing while driving

Thanks to the driving location sharing feature, a user can generate a link that directs to a map displaying its location while driving. Location sharing provides peace of mind to family members during a trip. This section describes the methods to manage the location-sharing link.

Check if the feature is available

If the trip sharing feature is enabled for your company, your API key carries out the feature access and a trip sharing link can be generated.

To check if the trip sharing feature is available for your API key, you can call the following code:

Create a link

To generate a link to share trips, use the following code:

The method takes a durationInSeconds parameter which indicates how long in seconds from now the sharing link will be valid.

CreateTripSharingLinkStatus

DKTripSharingLink

Retrieve a valid sharing link

To retrieve a link to share trips, use the following code:

The method takes a synchronizationType parameter. It will retrieve locally stored data if the value is CACHE, otherwise with the DEFAULT value it will call the DriveQuant’s servers.

GetTripSharingLinkStatus

Revoke a trip sharing link

To revoke a trip sharing link, use the following code:

RevokeTripSharingLinkStatus

Sharing data during the trip

The Trip Analysis component records the trip locally while it is in progress. The data are recorded with a period of one point per second. At the end of the trip, the SDK requests the driving analysis service and then retrieves the driving indicators.

In addition to this feature, the SDK is also able to share data with the server before the trip is completed. The data is transmitted at a lower frequency with a time interval of one point per minute.

Sharing information with the server allows you to store the trip data even if it has been interrupted, and if the data post at the end of the trip could not be performed. This can happen in very rare cases such as the destruction of the mobile phone.

By default, this setting is disabled but you can enable it by calling the following method with parameter enable to true:

To disable this setting, call the same method with the parameter set to false

Here is the list of data shared every minute by the SDK:

  • Date of trip start.

  • Duration of the trip in seconds.

  • Distance traveled in km.

  • Longitude of the current location.

  • Latitude of the current location.

  • Smartphone battery level.

  • StartMode of the trip recording: manual, GPS-based or beacon-based.

  • Beacon parameters: uuid, major, minor.

If the crash detection is enabled and if a confirmed crash is detected by DriveKit, the data will be shared every 10 seconds instead of 1 minute until the trip finished.

Access the trip trigger events

Why use trip triggers?

DriveKit's automatic start mode detects a trip and launches its recording immediately. This operating mode may not be appropriate for all use cases.

Your application may require other information or business logic before enabling the trip recording. For example, it may be appropriate to check that:

  • A connected device is near to the smartphone.

  • The trip recording is acceptable in a given time slot.

In this case, you may want to subscribe to the events that are indicative of the trip start but not necessarily launch the GPS sensor and the trip analysis.

This is why DriveKit allows you to subscribe to trigger events that indicate that a trip has probably started.

How does it work?

By default, this feature is disabled.

To enable this feature, DriveKit Trip Analysis should not be configured in automatic mode but in manual mode.

If DriveKit Trip Analysis is set to automatic mode, the trip will be recorded.

If DriveKit Trip Analysis is set to manual mode and you follow the instructions below, you will be able to listen for trip start trigger events but the trip analysis will not be started automatically.

To listen to trigger events that indicate a start of trip, even if the autostart is disabled, you can check the following property:

The potentialTripStart() method can return all StartMode values ; except MANUAL. Indeed, a trip manually started is considered as confirmed.

Get the arrival location of the last trip

This function returns the location of the end of the last trip recorded by the user.

The location is defined by GPS coordinates (latitude and longitude), along with the end date of the last trip and an accuracy indicator for the GPS reading.

You can use the end-of-trip coordinate for a variety of purposes, for example:

  • help the user find his vehicle

  • alert the customer that the user has reached a specific destination

  • create a geofence to locate the vehicle

The last trip corresponds to the last trip recorded by the DriveKit SDK, regardless of the mode of transport used.

To retrieve the location at which the last recorded trip ended, use the following method:

The method can return null if the user:

  • is not authenticated,

  • or didn’t make a trip since the authentication,

  • or hasn’t made any valid trips.

DKTripLocation

DKCoordinateAccuracy

For ease of use, this function provides a position accuracy indicator with a 3-level scale.

StartMode of the current trip

This method is now deprecated.

It is now possible to retrieve the start mode of the current trip using the getCurrentTripInfo() method.

Beacon usage

Configure beacons

The automatic trip detection feature is compliant with iBeacon Bluetooth beacons. A beacon is a Bluetooth low energy (BLE) device that broadcasts a universally unique identifier. This signal can be detected by the SDK and used to trigger the trip analysis.

In addition, the beacon is a smart and cost-effective solution for identifying the vehicle in which the driver is travelling.

You can add beacon identifiers to Trip Analysis module by calling the following method:

If you want to ignore major and minor values for trip detection, set them to -1.

If you want to remove beacons from SDK configuration, just call the method with an empty array.

Beacon required

To avoid the recording of unwanted trips (trips performed outside the vehicle where the beacon is placed), it is possible to automatically cancel the trip if the beacon is not "seen" several times during the trip. Generally, a trip will be cancelled in less than 6 minutes if the beacon is not in the vehicle.

By default, this setting is disabled but you can enable it by calling the following method:

To disable this settings, call the same method with the parameter set to false

Filter the beacon trigger to start trip recording

In very rare cases, it may be useful to avoid trip detection using the beacon but still need to validate the trip recording only if the beacon is near the smartphone during the trip.

In this case, the beacon is used in trip validation mode but not in trip detection mode.

If this advanced configuration is not used correctly, it may result in poor trip detection performance.

Please never use this feature without contacting DriveQuant to explain your use case and ensure that this particular mode is mandatory.

How does it work?

By default, if you have configured a beacon, its detection by the SDK will start a trip analysis.

In very rare cases (e.g. beacon in a vehicle and parked in close proximity to a living area), it might be useful to avoid the SDK to start a trip when a beacon is detected to reduce smartphone battery consumption.

Please note that beacon scan checks are always performed during the trip analysis, even if the configuration is called.

To disable the ability to start a trip analysis when a beacon is detected by DriveKit, you can call the following method:

This feature has no effect if the automatic trip detection mode is disabled.

Crash Detection

Principle

Crash detection features, included into the DriveKit Trip Analysis component, is able to collect and analyse smartphone sensors data to automatically detect when a car accident occurs.

DriveKit Trip Analysis analyzes signals from the GPS sensor and also from the motion sensors (accelerometer, gyrometer and magnetometer).

This feature is enabled if the following conditions are fulfilled:

  • Your API key has the access rights to use this service;

  • You have enabled the feature by following the instructions described in this section;

  • A trip has been detected and is being analysed.

  • The smartphone's sensors are functional.

  • The SDK is able to check the status of the required sensors.

The crash detection steps are:

  1. A trip is detected automatically or started manually and the trip recording starts.

  2. The crash feature detects a potential collision based on motion sensors.

  3. The GPS and motion data are pushed to the backend analysis services in charge of the signal processing and crash confirmation.

  4. The SDK receives a crash analysis service response with a status.

  5. If the crash is confirmed, the Trip analysis component can display a survey to ask the driver whether he needs assistance. This is an optional feature.

Enable crash detection

If the crash detection configuration is enabled for your company, your API key carries out the feature access and the crash detection will be enabled accordingly.

However, you can deactivate and reactivate the function if necessary using a dedicated setting.

A method is available in DriveKitTripAnalysis to enable or disable the feature:

Verify that the feature is available

It is possible to check if the crash detection is available for your configuration by checking the following property:

This property returns true if:

  • the required smartphone sensors are available and up and running;

  • your API key is allowed to use the feature;

If this property returns false, DriveKit will not start crash detection feature even if it has been previously activated with activateCrashDetection().

Configure crash detection feedback

Trip Analysis offers a mechanism to ask the user for feedback when an accident is confirmed by the crash analysis service.

Crash confirmation can be used to trigger a notification or display a screen which asks the driver to confirm the accident and whether assistance is required.

To disable the crash detection feedback, call the following method:

Listening to Crash events

TripListener interface provides two callbacks for crash events:

To receive these callbacks, the smartphone must be connected to a mobile network and the accident detection feature must be enabled for your organisation's API key.

Core
TripAnalysis
alert the user once a trip has been analyzed by the DriveQuant servers by displaying a notification
challenges
challenges

after calling the DriveKit SDK's method.

DKTripRecordingStartedState object is described .

Called each time a trip is confirmed. DKTripRecordingConfirmedState object is described .

DKTripRecordingCanceledState object is described .

Called when trip recording has ended, before sending trip data to DriveQuant's servers. DKTripRecordingFinishedState object is described .

object contains the trip analysis made on DriveQuant's server.

Called when a trip is started and confirmed, for each GPS point recorded by the SDK. Data available in TripPoint object are described .

Called every time the state of the SDK changed with the new state as parameter. States are described .

Called when a crash event is detected. Triggered if Crash Detection is enabled. Read more

called when crash feedback is enabled and a confirmed crash is detected. Triggered if Crash Detection is enabled. Read more

tripStarted(startMode: StartMode) This method has been deprecated to be replaced by: tripRecordingConfirmed(state: DKTripRecordingConfirmedState)

Called each time a trip is started. StartMode indicates which event starts the trip. Possible values are described .

tripCancelled(cancelTrip: CancelTrip) This method has been deprecated to be replaced by: tripRecordingCanceled(state: DKTripRecordingCanceledState)

Called when a trip is cancelled. CancelTrip indicates which event cancels the trip. Possible values are described .

This method has been deprecated to be replaced by: tripFinished(responseStatus: TripResponseStatus)

PostGeneric object contains raw data sent to DriveQuant's server, PostGenericResponse object contains the trip analysis made on DriveQuant's server. Detailed description of these data are available .

The SDK usage is included into acceptable use cases for requesting or being on the Battery Optimizations exceptions whitelist. For more information you can read the Android developer documentation on .

Some manufacturers add other battery optimizations. You can find tutorials on how to disable these battery optimizations for main Android device manufacturers .

For devices running Android 12 and above, it's required to ask the user for . Find below an example of how to ask Nearby Devices permission:

For devices running Android 13 and above, it's required to ask the user for . If the permission is not granted, the user will not receive notifications.

For Android 14 devices and above, it is now necessary to ask the user for this permission to display full screen notification for the feature.

A detailed description of BluetoothData class is available .

If you have configured the and the bluetooth device as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.

The DriveKit SDK is fully compatible with the standard.

A detailed description of BeaconData class is available .

"Regions are shared resources that rely on specific hardware capabilities. To ensure that all apps can participate in region monitoring, Core Location prevents any single app from monitoring more than 20 regions simultaneously."

If you have configured the beacon and the as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.

DriveKit is able to retrieve the battery level of a beacon and to add this information automatically in (only for the current trip), so that you can know, for instance, if the beacon battery of a user needs to be changed.

Getting the beacon battery level is not essential and if the Bluetooth access permission is not granted or your project not configured as mentioned below, the battery level will not be retrieved but this has no impact on the .

Attribute
Type
Description

This object also provides a method, getTrip(), to retrieve from the local database the saved if status is equal to tripValid. In case of error, this method returns nil.

Value
Description
Value
Description
Field
Type
Description
Field
Type
Description

This object is returned in the 's tripRecordingStarted() callback.

Field
Type
Description

This object is returned in the 's tripRecordingConfirmed() callback.

Field
Type
Description

This object is returned in the 's tripRecordingCanceled() callback.

Field
Type
Description

This object is returned in the 's tripRecordingFinished() callback.

Field
Type
Description
Value
Description
Value
Description
Attribute
Type
Description
Attribute
Type
Description
Default value, if not specified
Attribute
Type
Description
Attribute
Type
Description
Attribute
Type
Description
Attribute
Type
Description
Attribute
Type
Description
Enum value
Description
Enum value
Description
Enum value
Description
Value
Description
Attribute
Type
Description

If a trip is running when automatic trip detection is disabled, the trip will not be canceled. If you want to cancel the trip, you should also call method.

A detailed description of vehicle parameter is available .

STOPPING: The SDK is in this state when a potential trip end is detected. If the trip continues, the SDK goes back in RUNNING state. The can be configured.

Property
Type
Description
Value
Description
Property
Type
Description
Value
Description
Value
Description

This feature allows you to share to the server the location of a driver during all his trips. It is different from the feature where the user chooses to share his trips for a certain duration, thanks to a link showing his current trip on a map.

Once the feature is enabled, events will be available in the potentialTripStart() callback.

Property/Method
Type
Description
Name
Description

Trip Analysis offers a method to retrieve the of the current trip. The method returns null if no trip is running.

The DriveKit SDK is fully compatible with the standard.

A detailed description of BeaconData class is available .

If you have configured the beacon and the as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.

The crash detection comes with an optional feature to display an alert to the driver. This is described in the section.

To use this function, you need to enable the interface with the following method and a object:

To display a full-screen intent notification when a crash is detected while the phone is locked, your must declare that permission in the manifest of your app and runtime request the user to grant it. Learn more .

crashDetected(crashInfo:), triggered when a crash event is detected

crashFeedbackSent(crashInfo:, feedbackType: , severity:), triggered when crash feedback is enabled and a confirmed crash is detected. This callback will contain crash information and the feedback from the user.

⚠️
⚠️
⚠️
here
here
this topic
here
Nearby Devices permission
Notification runtime permission
Apple iBeacon™
developer.apple.com
trip's metadata
TripAnalysis auto start mode
startTrip()
here
beacon
bluetooth device
public class TripResponseStatus: NSObject {
    public let status: TripResponseStatusType
    public let itinId: String?
    public let localTripId: String?
    public let hasSafetyAndEcoDrivingScore: Bool
    public let info: [TripResponseInfo]
    public let error: TripResponseError?
    
    public func getTrip() -> DKTrip?
}

engineSpeedNotAvailable

The engine speed is not available. The trip analysis is performed with an estimated value of the engine speed.

engineSpeedIsNull

The engine speed is always at 0 rpm while the vehicle is moving. The trip analysis is performed but with an estimated value of the engine speed.

noVehicleCharacteristics

The vehicle characteristics are not set or some values are missing. The trip analysis is performed with generic vehicle model parameters.

dataLoss

More than 25% of data loss is detected during the trip.

distanceTooShort

The trip was analysed but the distance is not sufficient to provide an accurate energy analysis.

invalidVehicleCharacteristics

The vehicle characteristics are not in the range of available values. See vehicle characteristics for range limits.

invalidVehicleId

No vehicle found for the vehicleId provided to the API request.

noAccountSet

The account block is not set in the trip data.

noRouteObjectFound

The route block is not available in the trip data.

invalidRouteDefinition

Error when parsing the route block

noVelocityData

The vehicle or GPS velocity is not available

invalidSamplingPeriod

The input variables have an invalid acquisition period.

invalidCustomerId

Unknown account value. Unauthorised access.

noDateFound

The field vehicleDate or gpsDate is not available.

maxDailyRequestNumberReached

The trip could not be analyzed because you exceeded your daily request quota.

dataError

The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem.

invalidRouteVectors

The route vectors are not of the same size, the service cannot perform the analysis

missingBeacon

The beacon has not been detected and it is required to validate the trip analysis.

invalidBeacon

A beacon was detected during the trip but it does not have the correct identifiers

duplicateTrip

The duplicate trip feature is enabled and the trip has already been analysed

insufficientGpsData

The number of GPS points is too low

userDisabled

The driver is disabled, the service cannot perform the analysis

invalidUser

The user identifier is not valid.

invalidGpsData

The dates are inconstistent, the service cannot perform the analysis

invalidTrip

The trip has already been analysed by the service and considered as invalid

accountLimitReached

The maximum number of user account reached for the customer

latitude

Double

Latitude

longitude

Double

Longitude

speed

Double

Speed in km/h

accuracy

Double

Accuracy of the GPS data in meter

elevation

Double

Elevation in meter

distance

Double

Distance since the beginning of the trip in meter

heading

Double

Heading

duration

Double

Duration since the beginning of the trip in second

public class TripVehicle {
    public var carTypeIndex: Int = 1
    public var carEngineIndex: Int = 1
    public var carPower: Double = 150.0
    public var carMass: Double = 1400.0
    public var carGearboxIndex: Int = 2
    public var carConsumption: Double = 4.5
    public var carAutoGearboxNumber: Int = 0
    public var engineDisplacement: Double = 1_200.0
    public var frontTireSize: String?
    public var rearTireSize: String?
    public var length: Double
    public var width: Double
    public var height: Double
    public var engineCylinderNb: Int
    public var driveWheels: Int
}

proximityUuid

String

Beacon proximity UUID

major

Int

Beacon major value (optional)

minor

Int

Beacon minor value (optional)

macAddress

String

Required MAC address of the device

name

String

Optional display name of the device

public class DKCrashInfo {
    public let crashId: String
    public let date: Date
    public let probability: Int
    public let latitude: Double
    public let longitude: Double
    public let velocity: Double
    public let crashStatus: DKCrashStatus
    public let userLocationUrl: String?
}
public enum DKCrashStatus {
    case unconfirmed
    case confirmed
}

notification

DKCrashFeedbackNotification

Configuration of the notification

crashVelocityThreshold

Double

Minimal speed when the crash occurred.

For example, if crashVelocityThreshold is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user.

Default value: 0.0 km/h

title

String

Title that appears on the notification

message

String

Message that appears on the notification

crashAlert

DKCrashAlert

Enum value that describes how the user will be noticed when a feedback is asked

Default value: silence

silence

Device will not vibrate nor ring

vibration

Device will vibrate

soundAndVibration

Device will ring and vibrate

noCrash

User said that no crash occurred

confirmed

User confirmed a crash

noFeedback

User did not provide any feedback

none

User said that no crash occurred

minor

User confirmed a minor crash

critical

User confirmed a critical crash

here
Trip
StartMode
TripResponseStatus
TripResponseStatus
here
here
here
here
TripResponseStatus
here
here
here
here
here
val notification = TripNotification(
    title = "Trip notification title",
    content = "Trip notification content",
    iconId = R.drawable.ic_notification
)
DriveKitTripAnalysis.tripNotification = notification

title

String

Title of the notification

content

String

Content of the notification

iconId

Int

The icon Android resource identifier for notification

channelName

String

Name of the Android notification channel which is displayed in the app's notification settings.

If not set, the channel name takes the value of title attribute

channelId

String

Identifier of the Android notification channel used. The default value is dq_sdk_channel

notificationId

Int?

The identifier of the foreground notification. If not set, the value is a strictly positive random integer and changes every time a trip recording is running.

contentIntent

PendingIntent?

The Intent which will be launched when the user taps on the notification. Default value is null.

enableCancel

Boolean

If true, a cancel button will be displayed in notification that cancels the trip when pressed. Default value is false.

cancel

String?

Text of the cancel button. Default value is null.

cancelIconId

Int?

Icon resource of the cancel button. Default value is null.

fun activateAutoStart(activate: Boolean)
fun startTrip()
fun stopTrip()
fun cancelTrip()
fun setVehicle(vehicle: TripVehicle)
fun isTripRunning(): Boolean
fun getRecorderState(): State
fun getCurrentTripInfo(): DKTripInfo?
fun checkTripToRepost()
fun setStopTimeOut(timeOut: Int)
DriveKitTripAnalysis.tripSharing.isAvailable()
DriveKitTripAnalysis.getTripSharing().isAvailable()
val oneHourInSeconds = 3600
DriveKitTripAnalysis.tripSharing.createLink(oneHourInSeconds) { status: CreateTripSharingLinkStatus, data: DKTripSharingLink? ->
    // Check the status and manage the data
}
int oneHourInSeconds = 3600;
DriveKitTripAnalysis.getTripSharing().createLink(oneHourInSeconds, (CreateTripSharingLinkStatus status, DKTripSharingLink data) -> {
    // Check the status and manage the data
    return null;
});

code

String

Unique trip sharing code.

url

String

URL of the map that will display the current trip of the user.

startDate

Date

Link validity start date

endDate

Date

Link expiration date.

DriveKitTripAnalysis.tripSharing.getLink(SynchronizationType.DEFAULT) { status, data ->
    // Check the status and manage the data
}
DriveKitTripAnalysis.getTripSharing().getLink(SynchronizationType.DEFAULT, (GetTripSharingLinkStatus status, DKTripSharingLink data) -> {
    // Check the status and manage the data
    return null;
});

SUCCESS

The link has been successfully retrieved. Information is returned in data.

FAILED_TO_GET_CACHE_ONLY

An error occurred when trying to retrieve a link. Locally trip sharing link, if exists, is returned in data.

NO_ACTIVE_LINK

There is no active link for the user.

Information returned in data is null.

USER_NOT_CONNECTED

The user is not yet connected to DriveKit. Information returned in data is null.

UNAUTHENTICATED

The user has been disconnected.

Information returned in data is null.

FORBIDDEN

Your API key is not allowed to use the feature.

Information returned in data is null.

DriveKitTripAnalysis.tripSharing.revokeLink { status ->
    // Check the status and manage
}
DriveKitTripAnalysis.getTripSharing().revokeLink((RevokeTripSharingLinkStatus status) -> {
    // Check the status
    return null;
});

SUCCESS

The link has been successfully revoked.

NO_ACTIVE_LINK

There is no active link for the user.

ERROR

An error occurred when trying to revoke the link.

USER_NOT_CONNECTED

The user is not yet connected to DriveKit.

UNAUTHENTICATED

The user has been disconnected.

FORBIDDEN

Your API key is not allowed to use the feature.

fun enableSharePosition(enable: Boolean)
var monitorPotentialTripStart: Boolean
fun getLastTripLocation(): DKTripLocation?

date

Date

Date of the end of trip.

latitude

Double

Latitude of the end of the trip.

longitude

Double

Longitude of the end of the trip.

accuracyMeter

Double

GPS data accuracy value in meters.

fun getAccuracyLevel()

DKCoordinateAccuracy

GPS data accuracy level. Possible values are described below.

GOOD

The GPS accuracy is strictly below 10 meters.

FAIR

The GPS accuracy is between 10 and 30 meters.

POOR

The GPS accuracy is strictly above 30 meters.

fun getCurrentStartMode(): StartMode?
fun setBeacons(beacons: List<BeaconData>)
fun setBeaconRequired(required: Boolean)
var allowBeaconTripStart: Boolean
fun activateCrashDetection(activate: Boolean)
val isCrashDetectionAvailable: Boolean
fun enableCrashFeedback(config: DKCrashFeedbackConfig)
fun disableCrashFeedback()
customize the notification displayed during a trip analysis
crash detection
Crash Detection feedback

Working hours

The Working hours feature sorts the trips according to whether they are made during working hours. The trips are then automatically tagged as "BUSINESS" or "PERSONAL".

The feature also permits to set time slots during which the automatic starting mode is disabled, which offers more privacy control for the driver.

You can get that screen by calling the following method:

DriveKitNavigationController.shared.tripAnalysisUI?.getWorkingHoursViewController()

Trip recording widget

Principle

The widget is a button that let the user control the trip recording. Possible actions are:

  • Start a trip recording

  • Check that the current trip is being recorded

  • Stop a trip recording

  • Cancel a trip recording.

How to display the trip recording widget?

To integrate the trip recording widget into your application, simply add the code below:

let startStopTripButton = DriveKitTripAnalysisUI.shared.getTripRecordingButton(presentedIn: viewController)

The given viewController is used to present the stop trip confirmation dialog when the user taps the button in trip in progress state.

The given viewController is stored weakly by the button so you don’t need to worry about any retain cycle. Just pass the viewController that displays the button and you should be fine.

It can also be used when you call the DKTripRecordingButton public method showConfirmationDialog() on your button instance. This is useful if you need to programmatically display the dialog (for example, when the user taps a start trip notification).

Warning: This dialog won’t appear if the DKTripRecordingUserMode doesn’t allow the user to end a trip.

Trip recording widget configurations

The button has 4 configurations to cover all possible scenarios, and its display can be adjusted using the tripRecordingUserMode parameter.

  1. .none: The button is hidden and the trip recording is fully automatic. This is the simplest mode, and the one we prefer.

  2. .startStop: The button is displayed and the user has total control over the trip recording cycle: start, stop and cancel. In this configuration, autostart remains active.

  3. .startOnly: The user can start a trip manually but cannot stop or cancel it under any circumstances. Recording stops automatically. In this configuration, autostart remains active.

  4. .stopOnly: The user cannot start a trip manually. The start of a trip is detected automatically. The user can only stop the trip to get his results or cancel the recording if he is not the driver, for example.

The default value is .startStop.

To set the button mode, call the following method before displaying the button:

DriveKitTripAnalysisUI.shared.tripRecordingUserMode = .startStop
TripListener
TripListener
TripListener
TripListener
TripListener
Apple iBeacon™
user interface
DKCrashFeedbackConfig
DKCrashInfo
DKCrashInfo
CrashFeedbackType
CrashFeedbackSeverity
DKTrip
here
cancelTrip
duration of the stopping state
trip sharing with a link
here
here
StartMode

REST services

status

TripResponseStatusType

Can be tripValid or tripError. - tripValid means that the analyzed trip is valid. - tripError means that the trip has been analyzed but an error occurred and data is not valid.

itinId

String?

The id of the trip if status equals tripValid, otherwise nil.

localTripId

String?

Local and unique trip identifier generated by DriveKit SDK

hasSafetyAndEcoDrivingScore

Bool

If false, it means that the trip is valid but too short to be analyzed. In this case, there is no safety or eco-driving score. It cannot be equals to true if status is not tripValid.

info

If status equals tripValid, the DriveQuant servers returns a list of information codes. These are not errors.

error

If status equals tripError, error gives you more information about the error that occurred.

itinId

String

Trip unique identifier.

endDate

Date?

The end date of the trip.

startDate

Date?

The start date of the trip.

vehicleId

String?

The identifier of the vehicle used for this trip, if known.

transportationMode

TransportationMode

declaredTransportationMode

DKDeclaredTransportationMode?

departureCity

String?

The city of the departure of the trip.

arrivalCity

String?

The city of the arrival of the trip.

departureAddress

String?

The full address of the departure of the trip.

arrivalAddress

String?

The full address of the arrival of the trip.

unscored

Bool

true if has no safety and eco-driving score.

metadata

Dictionary<String, String>?

tripStatistics

DKTripStatistics?

brakeWear

DKBrakeWear?

tireWear

DKTireWear?

ecoDriving

DKEcoDriving?

ecoDrivingContexts

[DKEcoDrivingContext]?

fuelEstimation

DKFuelEstimation?

fuelEstimationContexts

[DKFuelEstimationContext]?

safety

DKSafety?

safetyContexts

[DKSafetyContext]?

safetyEvents

[DKSafetyEvents]?

driverDistraction

DKDriverDistraction?

pollutants

DKPollutants?

speedingStatistics

DKSpeedingStatistics?

speedLimitContexts

[DKSpeedLimitContext]?

calls

[DKCall]?

energyEstimation

DKEnergyEstimation?

advancedEnergyEstimation

[DKAdvancedEnergyEstimation]?

transportationMode

TransportationMode

passenger

Boolean?

true if the trip was made as a passenger, false if the trip was made as the driver.

comment

String?

The comment associated to this declaration.

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date

Date when the trip entered into the confirmation state.

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date?

Date when the trip was confirmed if the trip entered into the confirmation state.

cancelationReason

DKTripCancelationReason

Indicates how the trip was canceled.

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date

Date when the trip was confirmed if the trip entered into the confirmation state.

recordingEndDate

Date

gps

Automatic start when the SDK detects a change in user's position

beacon

Automatic start due to the presence of a beacon

manual

geozone

Automatic start when the SDK detects that you exit the zone where your vehicle may be parked

bluetooth

Automatic start by detecting a connection to a known vehicle's Bluetooth system

unknown_bluetooth

Automatic start by detecting a connection to an unknown vehicle's Bluetooth system

user

highSpeed

Trip canceled because speed was too high (train, airplane)

noSpeed

Trip canceled because speed was too slow to be made in a vehicle

noBeacon

noBluetoothDevice

missingConfiguration

Trip canceled because DriveKit was not configured

noLocationData

Trip canceled because no location data was recorded

reset

beaconNoSpeed

Trip canceled because the beacon is near the smartphone but there was no movement (zero or low speed)

bluetoothDeviceNoSpeed

Trip canceled because the Bluetooth device is connected to the smartphone but there was no movement (zero or low speed)

appKilled

The trip recording has been canceled due to an app termination. The trip is not sent to the DriveQuant's platform for analysis because it has never entered in confirmation state, or the Bluetooth device/Beacon is required but has not been detected.

carTypeIndex

Int

1

carEngineIndex

Int

1

carPower

Double

150

carMass

Double

Vehicle mass in kg (min: 700 kg, max: 3500 kg)

1400

carGearboxIndex

Int

2

carConsumption

Double

Combined fuel consumption [l/100km] measured during the New European Driving Cycle (NEDC). (min: 3 l/100km, max: 20 l/100km)

4.5

carAutoGearboxNumber

Int

Number of gear ratios for the automatic gearbox. This parameter is taken into account only if carGearboxIndex is set to 1.

6

engineDisplacement

double

Engine displacement in liters

1200

frontTireSize

string

Front tire size

"205/55/16"

rearTireSize

string

Rear tire size

"205/55/16"

length

double

Vehicle length in meter

4.5

width

double

Vehicle width in meter

1.8

height

double

Vehicle height in meter

1.45

driveWheels

Int

0

engineCylinderNb

Int

Number of cylinders

4

crashId

String

Crash unique identifier

date

Date

Crash date

Example: 2023-03-07T09:13:22.461+0200

probability

Int

Crash probability (in %)

latitude

Double

Coordinates (latitude) of the crash

longitude

Double

Coordinates (longitude) of the crash

velocity

Double

Velocity at time of crash

crashStatus

DKCrashStatus

Crash status enum. Two possible values: confirmed or unconfirmed

userLocationUrl

String?

Otherwise, it is nil.

user

highspeed

Trip cancelled because speed was too high (train, airplane)

noSpeed

Trip cancelled because speed was too slow to be in a vehicle

noBeacon

missingConfiguration

Trip cancelled because DriveKit was not configured

noGPSData

Trip cancelled because no GPS data was recorded

reset

beaconNoSpeed

Trip cancelled because the beacon is near the smartphone but there is no movement (zero or low speed)

bluetoothDeviceNoSpeed

Trip cancelled because the Bluetooth device is connected to the smartphone but there was no movement (zero or low speed)

localTripId

String

Local and unique trip identifier generated by DriveKit SDK.

⚠️ It is different from the itinId property returned in the Trip object. itinId corresponds to the unique trip identifier generated after the data analysis.

date

Date

Start date of the trip recording.

startMode

StartMode

SUCCESS

The link has been successfully created. Information is returned in data.

ACTIVE_LINK_ALREADY_EXISTS

A link already exists for this user.

Information returned in data is null.

ERROR

An error occurred, for instance when the user has no network.

Information returned in data is null.

USER_NOT_CONNECTED

The user is not yet connected to DriveKit. Information returned in data is null.

INVALID_DURATION

An error occurred when trying to create a link. The duration parameter must be strictly greater than 0. Information returned in data is null.

UNAUTHENTICATED

The user has been disconnected.

Information returned in data is null.

FORBIDDEN

Your API key is not allowed to use the feature.

Information returned in data is null.

References (Android)

TripResult

TripResult is a sealed class that indicates if the analyzed trip by the DriveQuant servers is valid or not, and it either provides information about the analyzed trip, or the cause of the error:

sealed class TripResult {
    data class TripValid(val itinId: String, val hasSafetyAndEcoDrivingScore: Boolean, val info: List<TripResponseInfo>) : TripResult() {
       fun getTrip(): Trip?
    }
    
    data class TripError(val tripResponseError: TripResponseError) : TripResult()

TripValid

Field
Type
Description

itinId

String

Unique trip identifier generated after the trip data analysis.

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

hasSafetyAndEcoDrivingScore

Boolean

If false, it means that the trip is too short to be analyzed. In this case, there is no safety or ecodriving score.

info

The DriveQuant servers returns a list of information codes. These are not errors.

TripResponseInfo

Value
Description

ENGINE_SPEED_NOT_AVAILABLE

The engine speed is not available. The trip analysis is performed with an estimated value of the engine speed.

ENGINE_SPEED_IS_NULL

The engine speed is always at 0 rpm while the vehicle is moving. The trip analysis is performed but with an estimated value of the engine speed.

NO_VEHICLE_CHARACTERISTICS

The vehicle characteristics are not set or some values are missing. The trip analysis is performed with generic vehicle model parameters.

DATA_LOSS

More than 25% of data loss is detected during the trip.

DISTANCE_TOO_SHORT

The trip was analysed but the distance is not sufficient to provide an accurate energy analysis.

INVALID_VEHICLE_CHARACTERISTICS

The vehicle characteristics are not in the range of available values. See vehicle characteristics for range limits.

INVALID_VEHICLE_ID

No vehicle found for the vehicleId provided to the API request.

TripError

Property
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK.

tripResponseError

TripResponseError

The reason why the trip is analyzed as invalid.

TripResponseError

Value
Description

NO_ACCOUNT_SET

The account block is not set in the trip data.

NO_ROUTE_OBJECT_FOUND

The route block is not available in the trip data.

INVALID_ROUTE_DEFINITION

Error when parsing the route block

NO_VELOCITY_DATA

The vehicle or GPS velocity is not available

INVALID_SAMPLING_PERIOD

The input variables have an invalid acquisition period.

INVALID_CUSTOMER_ID

Unknown account value. Unauthorised access.

NO_DATE_FOUND

The field vehicleDate or gpsDate is not available.

MAX_DAILY_REQUEST_NUMBER_REACHED

The trip could not be analyzed because you exceeded your daily request quota.

DATA_ERROR

The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem.

INVALID_ROUTE_VECTORS

The route vectors are not of the same size, the service cannot perform the analysis

MISSING_BEACON

The beacon has not been detected and it is required to validate the trip analysis.

INVALID_BEACON

A beacon was detected during the trip but it does not have the correct identifiers

DUPLICATE_TRIP

The duplicate trip feature is enabled and the trip has already been analysed

INSUFFICIENT_GPS_DATA

The number of GPS points is too low

USER_DISABLED

The driver is disabled, the service cannot perform the analysis

INVALID_USER

The user identifier is not valid.

INVALID_GPS_DATA

The dates are inconstistent, the service cannot perform the analysis

INVALID_TRIP

The trip has already been analysed by the service and considered as invalid

ACCOUNT_LIMIT_REACHED

The maximum number of user account reached for the customer

UNKNOWN_ERROR

The error is not yet handled by the DriveKit SDK.

Trip

Field
Type
Description

itinId

String

Trip unique identifier.

endDate

Date

The end date of the trip.

startDate

Date?

The start date of the trip.

vehicleId

String?

The identifier of the vehicle used for this trip, if known.

transportationMode

TransportationMode

The transportation mode used for this trip, among: CAR, MOTO, TRUCK, BUS, TRAIN, BOAT, BIKE, FLIGHT, SKIING, ON_FOOT, IDLE, OTHER, UNKNOWN.

declaredTransportationMode

DeclaredTransportationMode?

departureCity

String

The city of the departure of the trip.

arrivalCity

String

The city of the arrival of the trip.

departureAddress

String

The full address of the departure of the trip.

arrivalAddress

String

The full address of the arrival of the trip.

unscored

Boolean

true if has no safety and eco-driving score.

metaData

Map<String, String>

tripStatistics

TripStatistics?

brakeWear

BrakeWear?

tireWear

TireWear?

ecoDriving

EcoDriving?

ecoDrivingContexts

List<EcoDrivingContext>

fuelEstimation

FuelEstimation?

fuelEstimationDrivingContexts

List<FuelEstimationDrivingContext>

safety

Safety?

safetyContexts

List<SafetyContext>

safetyEvents

List<SafetyEvent>?

driverDistraction

DriverDistraction?

pollutants

Pollutants?

speedingStatistics

SpeedingStatistics?

speedLimitContexts

List<SpeedLimitContext>?

calls

List<Call>?

energyEstimation

EnergyEstimation?

advancedEnergyEstimations

List<AdvancedEnergyEstimation>?

DeclaredTransportationMode

The user has the possibility to declare the transportation mode that was used during a trip to confirm the one detected or to change it, and to declare whether the trip was made as a passenger or as the driver.

Here is the description of the corresponding object:

Field
Type
Description

transportationMode

TransportationMode

The transportation mode declared by the user for this trip, among: CAR, MOTO, TRUCK, BUS, TRAIN, BOAT, BIKE, FLIGHT, SKIING, ON_FOOT, IDLE, OTHER, UNKNOWN.

passenger

Boolean?

true if the trip was made as a passenger, false if the trip was made as the driver.

comment

String?

The comment associated to this declaration.

DKTripRecordingStartedState

Field
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

DKTripRecordingConfirmedState

Field
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date

Date when the trip entered into the confirmation state.

DKTripRecordingCanceledState

Field
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date?

Date when the trip was confirmed if the trip entered into the confirmation state.

cancelationReason

DKTripCancelationReason

Indicates how the trip was canceled.

DKTripRecordingFinishedState

Field
Type
Description

localTripId

String

Local and unique trip identifier generated by DriveKit SDK

startMode

StartMode

recordingStartDate

Date

recordingConfirmationDate

Date

Date when the trip entered into the confirmation state.

recordingEndDate

Date

StartMode

StartMode indicates how the trip is started. It is an enum with the following values:

Value
Description

Value

Description

GPS

Automatic start when the SDK detects a change in user position

BEACON

Automatic start due to the presence of a beacon

MANUAL

GEOZONE

Automatic start when the SDK detects that you exit the zone where your vehicle may be parked

BLUETOOTH

Automatic start by detecting a connection to a vehicle's Bluetooth system

UNKNOWN_BLUETOOTH

Automatic start by detecting a connection to a unknown vehicle's Bluetooth system

BICYCLE_ACTIVITY

Automatic start by detecting a bicycle activity

CONNECTED_CAR

Automatic start when the SDK detects that your smartphone has been connected to an Android Auto or Automotive OS system

DKTripCancelationReason

Value
Description

USER

HIGH_SPEED

Trip canceled because speed was too high (train, airplane)

NO_SPEED

Trip canceled because speed was too slow to be made in a vehicle

NO_BEACON

NO_BLUETOOTH_DEVICE

MISSING_CONFIGURATION

Trip canceled because DriveKit was not configured

NO_LOCATION_DATA

Trip canceled because no location data was recorded

RESET

BEACON_NO_SPEED

Trip canceled because the beacon is near the smartphone but there was no movement (zero or low speed)

BLUETOOTH_DEVICE_NO_SPEED

Trip canceled because the Bluetooth device is connected to the smartphone but there was no movement (zero or low speed)

APP_KILLED

The trip recording has been canceled due to an app termination. The trip is not sent to the DriveQuant's platform for analysis because it has never entered in confirmation state, or the Bluetooth device/Beacon is required but has not been detected.

TripPoint

TripPoint is an object that contains data for each location registered by the SDK.

Attribute
Type
Description

latitude

Double

Latitude

longitude

Double

Longitude

speed

Double

Speed in km/h

accuracy

Double

Accuracy of the GPS data in meter

elevation

Double

Elevation in meter

distance

Double

Distance since the beginning of the trip in meter

heading

Double

Heading

duration

Double

Duration since the beginning of the trip in second

TripVehicle

TripVehicle is an object that contains vehicle detailed characteristics.

data class TripVehicle (
    val carTypeIndex: Int = 1,
    val carEngineIndex: Int = 1,
    val carPower: Double = 150.0,
    val carMass: Double = 1400.0,
    val carGearboxIndex: Int = 2,
    val carConsumption: Double = 4.5,
    val carAutoGearboxNumber: Int = 0,
    val engineDisplacement: Double = 1200.0,
    val frontTireSize: String? = null,
    val rearTireSize: String? = null,
    val length: Double? = null,
    val width: Double? = null,
    val height: Double? = null,
    val engineCylinderNb: Int? = null,
    val driveWheels: Int? = null
)
Attribute
Type
Description
Default value, if not specified

carTypeIndex

Int

1

carEngineIndex

Int

1

carPower

Double

150

carMass

Double

Vehicle mass in kg (min: 700 kg, max: 3500 kg)

1400

carGearboxIndex

Int

2

carConsumption

Double

Combined fuel consumption [l/100km] measured during the New European Driving Cycle (NEDC). (min: 3 l/100km, max: 20 l/100km)

4.5

carAutoGearboxNumber

Int

Number of gear ratios for the automatic gearbox. This parameter is taken into account only if carGearboxIndex is set to 1.

6

engineDisplacement

Double

Engine displacement in liters

1200

frontTireSize

String?

Front tire size

"205/55/16"

rearTireSize

String?

Rear tire size

"205/55/16"

length

Double?

Vehicle length in meter

4.5

width

Double?

Vehicle width in meter

1.8

height

Double?

Vehicle height in meter

1.45

engineCylinderNb

Int?

Number of cylinders

4

driveWheels

Int?

0

BeaconData

BeaconData is an object that contains beacon characteristics.

Attribute
Type
Description

proximityUuid

String

Beacon proximity UUID

major

Int

Beacon major value (set to -1 to ignore value)

minor

Int

Beacon minor value (set to -1 to ignore value)

BluetoothData

BluetoothData is an object that contains the Bluetooth device characteristics.

Attribute
Type
Description

macAddress

String

Required MAC address of the device

name

String

Optional display name of the device

DKCrashInfo

Crash information object have the following structure:

Attribute
Type
Description

crashId

String

Crash unique identifier

date

Date

Crash date

Example: 2023-03-07T09:13:22.461+0200

probability

Short

Crash probability (in %)

latitude

Double

Coordinates (latitude) of the crash

longitude

Double

Coordinates (longitude) of the crash

velocity

Double

Velocity at time of crash

crashStatus

DKCrashStatus

Crash status enum. Two possible values: CONFIRMED or UNCONFIRMED

userLocationUrl

String?

Otherwise, it is null.

DKCrashFeedbackConfig

DKCrashFeedbackConfig is an object used to configure the Crash Detection feedback feature.

Attribute
Type
Description

notification

DKCrashFeedbackNotification

Configuration of the notification

crashVelocityThreshold

Double

Minimal speed when the crash occurred.

For example, if crashVelocityThreshold is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user.

Default value : 0.0 km/h

DKCrashFeedbackNotification

Attribute
Type
Description

icon

Int

Resource identifier of the notification icon

channelId

String

Android channel identifier. Default value: dq_sdk_crash_channel

notificationId

Int

Android notification identifier

title

String

Title that appears on the notification

message

String

Message that appears on the notification

activity

Class<*>

Activity to display

crashAlert

DKCrashAlert

Object that describes how the user will be noticed when a feedback is asked Default value : SILENCE

DKCrashAlert

Attribute
Description

SILENCE

Device will not vibrate or ring

VIBRATION

Device will vibrate

SOUND_AND_VIBRATION

Device will ring and vibrate

CrashFeedbackType

Enum value
Description

NO_CRASH

User said that no crash occurred

CRASH_CONFIRMED

User confirmed a crash

NO_FEEDBACK

User did not provide any feedback

CrashFeedbackSeverity

Enum value
Description

NONE

User said that no crash occurred

MINOR

User confirmed a minor crash

CRITICAL

User confirmed a critical crash

TripResponseStatus (Deprecated)

TripResponseStatus is a sealed class that indicates if the analyzed trip by the DriveQuant servers is valid or not:

TripValid

Field
Type
Description

hasSafetyAndEcoDrivingScore

Boolean

If false, it means that the trip is too short to be analyzed. In this case, there is no safety or ecodriving score.

info

The DriveQuant servers returns a list of information codes. These are not errors.

TripResponseError

CancelTrip (Deprecated)

CancelTrip indicates how the trip was cancelled. It is an enum with the following values:

Value
Description

USER

HIGHSPEED

Trip cancelled because speed was too high (train, airplane)

NO_SPEED

Trip cancelled because speed was too slow to be made in a vehicle

NO_BEACON

MISSING_CONFIGURATION

Trip cancelled because DriveKit was not configured

NO_GPS_DATA

Trip cancelled because no GPS data was recorded

RESET

BEACON_NO_SPEED

Trip cancelled because the beacon is near the smartphone but there was no movement (zero or low speed)

BLUETOOTH_DEVICE_NO_SPEED

Trip cancelled because the Bluetooth device is connected to the smartphone but there was no movement (zero or low speed)

DeviceConfigEvent (Deprecated)

DeviceConfigEvent indicates when the device configuration has been changed. It is a sealed class with the following values:

BluetoothSensorStateChanged

This data class is called when the Bluetooth device sensor has been turned on or off.

  • btEnabled : Equals true when the Bluetooth sensor has been turned on.

  • btRequired : Equals true when the DriveKit configuration needs the Bluetooth sensor (when beaconRequired is set to true or when TripAnalysis component is configured with is at least one beacon or one Bluetooth device).

GpsSensorStateChanged

This data class is called when the GPS sensor has been turned on or off

  • isEnabled: Equals true when the GPS sensors has been turned on.

User interface

The Trip Analysis UI module is an open source graphical library created to incorporate a user interface for trip analysis management into your mobile application.

It contains 3 main features :

  1. Working hours ;

  2. Feedback crash detection ;

  3. A widget to control the trip recording.

Working Hours

The working hours feature sorts the trips according to whether they are made during working hours.

If the driver activates the feature, he can determine for each day of the week the time slots on which he wants the trips to automatically be considered as:

  • professional,

  • personal,

  • or not recorded at all.

Feedback crash detection

The TripAnalysis internal module contains a crash detection feature. Once activated, using the phone's sensors, the SDK is able to identify if a crash has occurred, and so help the emergency services to intervene.

To enhance this feature, the TripAnalysis UI module contains a graphical interface that can be activated. It informs the driver that a crash has been detected so he can confirm it and ask for assistance if needed.

Trip recording widget

The Trip Analysis user interface includes a widget to help the user to control the trip recording.

The appearance of the button is updated according to the trip status:

  1. ​​If there are no trip in progress, the user can manually start the trip analysis.

  2. If a trip is being recorded, this component displays the start time of the trip, the duration of the recording and the travelled distance. In this case, the user can stop the analysis to obtain his or her driving scores.

Three options are proposed to the user if he clicks on the button while a trip is being recorded:

  1. The user can declare that the trip is still in progress, in which case recording will continue.

  2. The user can declare that he has completed his trip, in which case the trip will be analysed and he will receive his driving score.

  3. The user can cancel the trip recording if he is not the driver, in this case the trip will not be analysed.

Custom metadata

If your use case requires it, it is possible to add your own data in the trip analysis request. For example, it can be data that is specific to your trip, application or user identification system.

Set metadata

You can add additional metadata to your trip by calling the following method:

fun setTripMetaData(metaData: HashMap<String, String>?)

The metadata must be represented as a key/value object where the key and value have a String type.

The metadata can be set any time before the end of a trip.

If metadata is sent, it will also be added to the push data request in the metaData field.

Get metadata

It is possible to get a copy of configured metadata thanks to the following method on DriveKitTripAnalysis:

fun getTripMetaData(): HashMap<String, String>?

Note: Any modification on the returned object has no effect on the metadata sent with a trip.

Update metadata

To update a value in metadata, call the following method:

fun updateTripMetaData(key: String, value: String?)

Delete a specific metadata

To delete a specific value in metadata, call the following method:

fun deleteTripMetadata(key: String)

Delete all metadata

To delete all values in metadata, call this method:

fun deleteTripMetadata()

Get started

Prerequisite

Integration

The Trip Analysis UI module is available on Cocoapods master repo. To access the framework in the repository, add the following lines to your Podfile:

target 'my-target' do
  pod 'DriveKitTripAnalysisUI'
end

Then, run pod install.

Initialization

import DriveKitTripAnalysisUI

Then, to initialize Trip Analysis UI SDK in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate:

import DriveKitCoreModule
import DriveKitCommonUI
import DriveKitTripAnalysisModule
import DriveKitTripAnalysisUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    DriveKit.shared.initialize()
    DriveKitTripAnalysis.shared.initialize(appLaunchOptions: launchOptions)
    DriveKitUI.shared.initialize()
    DriveKitTripAnalysisUI.shared.initialize()
    ...    
}

Get started

Prerequisite

Integration

To add the Trip Analysis UI module to your app, add the following lines to your dependencies in your application build.gradle file:

dependencies {
   implementation 'com.drivequant.drivekit:drivekit-trip-analysis-ui:$drivekitui_version'
}

Replace $drivekitui_version with the DriveKit version you are using in your app

Initialization

Then, to initialize the Trip Analysis UI module in your app, you must call the initialization method in onCreate method of your Application class:

class MyApplication : Application() {
   override fun onCreate() {
      super.onCreate()
      DriveKit.initialize()
      DriveKitTripAnalysis.initialize(...)
      DriveKitUI.initialize()
      DriveKitTripAnalysisUI.initialize()
      (…)
   }
}
public class DriveQuantApplication extends Application {
   @Override
   public void onCreate() {
   	super.onCreate();
   	DriveKit.initialize();
        DriveKitTripAnalysis.initialize(...)
   	DriveKitUI.initialize();
   	DriveKitTripAnalysisUI.initialize();
   	(…)
   }
}

Driver alert in case of crash

Principle

The crash detection feature includes an interface that informs the driver that a crash has been detected so he can confirm it to automatically call for help if needed.

Enable crash detection feedback

By default, the crash detection feedback is disabled. When this feature is enabled, the crash detection feedback displays a notification or a screen and calls an emergency number when a crash is confirmed by the driver.

To enable crash detection feedback, the following method needs to be called:

fun enableCrashFeedback(roadsideAssistanceNumber: String, config: DKCrashFeedbackConfig)

With the following parameters:

Attribute
Type
Description

roadsideAssistanceNumber

String

Emergency number that will be called if there is a crash.

config

DKCrashFeedbackConfig

Configuration of the feedback.

DKCrashFeedbackConfig

Attribute
Type
Description

notification

DKCrashFeedbackNotification

Configuration of the notification.

crashVelocityThreshold

Double

Minimal speed when the crash occurred. For example, if crashVelocityThreshold is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user. Default value : 0.0 km/h

DKCrashFeedbackNotification

Attribute
Type
Description

title

String

Title that appears on the notification.

message

String

Message that appears on the notification

crashAlert

DKCrashAlert

Object that describes how the user will be noticed when a feedback is asked. Default value : SILENCE

DKCrashAlert

Attribute
Description

SILENCE

Device will not vibrate or ring

VIBRATION

Device will vibrate

SOUND_AND_VIBRATION

Device will ring and vibrate

Disable Feedback crash detection

To disable crash detection feedback, call the following method:

fun disableCrashFeedback()

Test your integration with the crash simulator

To simulate a car accident, simply install the trip simulator and start a simulation with the configuration TRIP_WITH_CRASH.

Register to the Crash Notification API

Our platform can share a collision report that contains information about the accident.

This information can be used to:

  • trigger the intervention of an assistance service,

  • and initiate the accident management process.

Location sharing

Location sharing while driving provides peace of mind to family members. The graphical interface helps the user to enable location sharing and create a link that displays his location on a map to a friend or family member while driving.

The feature is implemented across three distinct screens:

  1. Introduction Screen: The feature is disabled by default. The first screen explains the location-sharing principle.

  2. Duration Selection Screen: On the second screen, the user can choose the duration for sharing his trip location. The available options include one day, one week, or one month.

  3. Active Sharing Screen: The last screen confirms that location sharing is active. It includes a button that allows the user to generate and share a link displaying his real-time location. Additionally, it displays the remaining time before the link expires.

To integrate and display this feature within your application, invoke the following method:

Working hours

The Working hours feature sorts the trips according to whether they are made during working hours. The trips are then automatically tagged as BUSINESS or PERSONAL.

The feature also permits to set time slots during which the automatic starting mode is disabled, which offers more privacy control for the driver.

You can start displaying that screen by calling the following method:

Trip recording widget

Principle

The widget is a button that lets the user control the trip recording. Possible actions are:

  • Start a trip recording

  • Check that the current trip is being recorded

  • Stop a trip recording

  • Cancel a trip recording.

How to display the trip recording widget?

There are two ways to integrate the trip recording widget into your application:

The first one is embedding it in XML layout:

The second way is getting it from DriveKitTripAnalysisUI:

If you need to programmatically display the stop trip confirmation dialog (for example, when the user taps a start trip notification), you can call the public method showConfirmationDialog() of the DKTripRecordingButton instance.

Warning: This dialog won’t appear if the DKTripRecordingUserMode doesn’t allow the user to end a trip.

Trip recording widget configurations

The button has 4 configurations to cover all possible scenarios, and its display can be adjusted using the tripRecordingUserMode parameter.

  1. NONE: The button is hidden and the trip recording is fully automatic. This is the simplest mode, and the one we prefer.

  2. START_STOP: The button is displayed and the user has total control over the trip recording cycle: start, stop and cancel. In this configuration, autostart remains active.

  3. START_ONLY: The user can start a trip manually but cannot stop or cancel it under any circumstances. Recording stops automatically. In this configuration, autostart remains active.

  4. STOP_ONLY: The user cannot start a trip manually. The start of a trip is detected automatically. The user can only stop the trip to get his results or cancel the recording

The default value is START_STOP.

To set the button mode, call the following method:

Trip Simulator

To verify the DriveKit Trip Analysis component integration into your app, it is recommended to perform tests in real conditions.

Before carrying out driving tests, it may be useful to validate the implementation of the SDK in your application.

However, it is not possible to emulate GPS data from development tools such as Android Studio. It is possible to simulate a trip using the simulator in Xcode, but the trip options are very limited.

For this purpose, DriveQuant provides a trip simulation component based on recorded GPS data.

The Trip Simulator component allows to validate the following features:

  • the automatic start;

  • the trip recording life cycle;

  • graphical display after the end of the trip;

  • the application's behaviour in the case of alternative trips;

  • crash detection during a trip, with user’s feedback.

This section gives step-by-step instructions for integrating the DriveKit SDK test component into your application.

References

This section describes the main response codes of the trip analysis API.

Vehicle body type

Engine type

Gearbox type

Drive wheels type

Weather code

Transportation Mode

Road conditions

Error codes

⚠️ It is different from the itinId property returned in the object.

[]

?

The transportation mode used for this trip, see for the description of the possible values.

The transportation mode declared by the user. See .

Your specific data attached to the trip. See .

Indicators that characterize the trip conditions. See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

The transportation mode declared by the user for this trip. See for the description of the possible values.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

Possible values are described .

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

Date when DriveKit has terminated the trip recording. ⚠️ It is not the trip end date returned in after DriveQuant platform's analysis..

Trip started manually by calling the method

Trip canceled by calling the method

Trip canceled because the beacon was not detected while it was

Trip canceled because the Bluetooth device was not detected while it was .

Trip canceled because SDK configuration has been .

Vehicle power in hp. This value must be entered in horsepower. In case you only have the engine power in kW you can apply the following formula: P[hp]=P[kW]/0.7355P [hp] = P [kW] / 0.7355P[hp]=P[kW]/0.7355 (min: 40 hp, max 450 hp)

When a crash is confirmed and is activated, an URL of the map that will display the location data is returned.

Trip cancelled by calling the method

Trip cancelled because the beacon was not detected while it was

Trip cancelled because SDK configuration has been

⚠️ It is different from the startDate property returned in the object.

The which triggered the trip recording.

💡 You have to call the method to in your workflow.

If is TripValid, it means that the analyzed trip is valid. Additional information are available:

⚠️ It is different from the itinId property returned in the object.

List<>

This object also provides a method, getTrip(), to retrieve from the local database the saved .

If is TripError, it means that the trip has been analyzed but an error occurred and data is not valid. Additional error information are available:

⚠️ It is different from the itinId property returned in the object. itinId corresponds to the unique trip identifier generated after the data analysis.

The transportation mode declared by the user. See .

Your specific data attached to the trip. See .

Indicators that characterize the trip conditions. See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

See .

This object is returned in the 's tripRecordingStarted() callback.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

This object is returned in the 's tripRecordingConfirmed() callback.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

This object is returned in the 's tripRecordingCanceled() callback.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the recalculated trip start date returned in after DriveQuant platform's analysis.

Possible values are described .

This object is returned in the 's tripRecordingFinished() callback.

⚠️ It is different from the itinId property returned in the object, which corresponds to the unique trip identifier generated after the data analysis.

Indicates how the trip started. Possible values are describe .

Date when DriveKit has started the trip recording. ⚠️ It is not the trip start date returned in after DriveQuant platform's analysis.

Date when DriveKit has terminated the trip recording. ⚠️ It is not the trip end date returned in after DriveQuant platform's analysis.

Trip started manually by calling the method

Trip canceled by calling the method

Trip canceled because the beacon was not detected while it was

Trip canceled because the Bluetooth device was not detected while it was .

Trip canceled because SDK configuration has been .

Vehicle power in hp. This value must be entered in horsepower. In case you only have the engine power in kW you can apply the following formula: (min: 40 hp, max 450 hp)

When a crash is confirmed and is activated, an URL of the map that will display the location data is returned.

If is TripValid, it means that the analyzed trip is valid. Additional information are available:

List<>

If is TripResponseError, it means that the trip has been analyzed but an error occurred and data is not valid. Additional error information are available in the enum.

Trip cancelled by calling the method

Trip cancelled because the beacon was not detected while it was

Trip cancelled because SDK configuration has been .

Metadata is persisted, so if you want to send it only for one trip, you need to remove it at the end of the trip, on the callback, by checking if state is INACTIVE.

Before starting DriveKit Trip Analysis UI integration, make sure that you have initialized TripAnalysis and modules, especially if you have .

On this , you also have a demo app and source code of Driver Data UI that you can use as an example.

If you have , the Trip Analysis UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitTripAnalysisUI:

Before starting DriveKit Vehicle UI integration, make sure that TripAnalysis and modules are initialized, especially if you have .

On a, you can find a demo app and the source code of Permissions Utils UI that you can use as an example.

If you have , the Trip Analysis UI module must also be manually initialized.

In order to check your integration and test the crash detection feature, you can use the trip simulator described in section .

If you want to know more and if you need to collect crash data on your platform, we invite you to contact us by email at

You can try the Trip Simulator feature in the .

Value
Type
Description
Value
Description
Value
Description
Value
Description
Value
Description
Value
Description
Value
Description
Comment
Status
Code
Comment
Description
P[hp]=P[kW]/0.7355P [hp] = P [kW] / 0.7355P[hp]=P[kW]/0.7355
Custom metadata
​Drive wheels type​
push crash data
TripListener
TripListener
TripListener
TripListener
sdkStateChanged(state: State)
Github repository
Github repository
contact@drivequant.com
Trip
TripResponseInfo
TripResponseError
DeclaredTransportationMode
Trip
here
TripResponseStatus
Trip
here
TripResponseStatus
Trip
here
TripResponseStatus
here
Trip
here
TripResponseStatus
TripResponseStatus
startTrip
cancelTrip
cancelTrip
required
required
required
reset
reset
disabled the SDK auto-initialization
Trip
StartMode
TripResult
Trip
TripResult
TripResponseStatus
TripResponseStatus
tripResponseError
retrieve an existing link
disabled the SDK auto-initialization
DriveKitTripAnalysisUI.shared.getTripSharingViewController()
DriveKitNavigationController.tripAnalysisUIEntryPoint?.startWorkingHoursActivity(context)
TripAnalysisUIEntryPoint entryPoint = DriveKitNavigationController.INSTANCE.getTripAnalysisUIEntryPoint();
if (entryPoint != null) {
   entryPoint.startWorkingHoursActivity(this);
}
<fragment
    android:id="@+id/start_stop_trip_button"
    android:name="com.drivequant.drivekit.tripanalysis.triprecordingwidget.recordingbutton.DKTripRecordingButton"
    android:layout_width="match_parent"
    android:layout_height="60dp" />
fun newTripRecordingButtonFragment(): DKTripRecordingButton
var tripRecordingUserMode: DKTripRecordingUserMode

1

Car

Compact

2

Car

Sedan

3

Car

Luxury vehicle

4

Car

Estate car

5

Car

Minivan

6

Car

4x4, SUV

7

Car

Sports car

8

Car

Convertible

9

Car

Commercial vehicle

200

Truck

2-axle trailer

201

Truck

3-axle trailer

202

Truck

4-axle trailer

203

Truck

2-axle tractor

204

Truck

3-axle tractor

1

Gasoline

2

Diesel

3

Electric vehicle

4

Gasoline-electric hybrid

5

Diesel-electric hybrid

6

Biofuel

7

Bi-fuel gasoline bioethanol

8

Dual-fuel gasoline NGV

9

Dual-fuel gasoline LPG

10

Not available

11

Plug-in gasoline hybrid

12

Hydrogen

1

Automatic

2

Manual 5-speed

3

Manual 6-speed

4

Manual 7-speed

5

Manual 8-speed

0

Front-wheel drive

1

Rear-wheel drive

2

Four-wheel drive

0

Unknown

1

Clear sky

2

Cloudy

3

Foggy

4

Rainy

5

Snowy

6

Icy

0

Unknown

1

Passenger car

2

Motorcycle

3

Heavy-duty vehicle

4

Bus

5

Coach

6

Rail trip

7

Boat trip

8

Bike trip

9

Plane

10

Ski

11

On foot

12

Idle

13

Other

0

Traffic jam

This corresponds to vehicle displacements of less than 100 meters and performed with speeds below 10 km/h

1

Heavy urban traffic

Speed below 30 km/h and distance between two stops greater than 100 m

2

City

30 km/h < Speed < 65 km/h

3

Suburban

65 km/h < Speed < 96 km/h

4

Expressways

Speed > 96 km/h

true

0

OK

The data are correct and the process ran fine

false

10

Mandatory account object not found

The « account» block is not set

false

13

Mandatory route object not found

The « route » block is not available → The trip analysis is not possible

false

14

Invalid route definition

Error when parsing the Route block

false

15

Velocity data is missing

The vehicle or GPS velocity is not available → The trip analysis is not possible

true

16

Engine speed not available

The engine speed is not available → The trip analysis is performed with an estimated value of the engine speed

true

17

Engine speed is null

The engine speed is always at 0 rpm while the vehicle is moving → The trip analysis is performed but with an estimated value of the engine speed

true

18

One or more vehicle parameters are missing (<list of missing parameters>). Default values are used

The vehicle characteristics are not set or some values are missing → The trip analysis is performed with generic vehicle model parameters

false

19

Invalid sampling period: one second recording interval is recommended for input variables

The input variables have an invalid acquisition period → The trip analysis is not possible

true

20

More than 25% of data loss

More than 25% of data loss is detected during the trip

false

21

Invalid customerId

Unknown account value. Unauthorized access.

false

23

Date data is missing

The field vehicleDate or gpsDate is not available → The trip analysis is not possible

false

24

Daily request number is reached

The maximum daily request number is reached

true

25

The trip distance is lower than 1 km

This error message indicates that the trip was analysed but the distance is not sufficient to provide an accurate energy analysis

false

26

Your request could not be processed. If the problem persist, please contact us

The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem

false

27

Your request could not be processed. If the problem persist, please contact us

The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem

true

28

One or more vehicle parameters are out of bound (<list of missing parameters>)

The vehicle characteristics are not in the range of available values. See vehicle characteristics for range limits

false

29

Beacon is missing

The beacon has not been detected and it is required to validate the trip analysis

false

30

Invalid beacon data

A beacon was detected during the trip but it does not have the correct identifiers

false

31

A similar trip has already been processed and stored with same account

The duplicate trip feature is enabled and the trip has already been analyzed

true

32

The vehicleId is invalid

No vehicle found for the vehicleId provided into the API request

false

33

The total of GPS points are under 10

There is not enough GPS points to perform an analysis

false

34

The account of this driver is disabled

The driver account is disabled

false

35

The automatic driver account creation is disabled

The automatic creation is disabled, use a valid authentication process to create the driver account

false

36

All the dates are negatives

The field vehicleDate or gpsDate contains negative values → The trip analysis is not possible

false

37

Your request could not be processed. If the problem persist, please contact us

The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem

false

38

Unable to create a new driver: maximum number of drivers reached for the account

The trip's driver cannot be created automatically, because you reached the maximum allowed number of drivers for your account. Please contact us to increase this threshold.

Transportation Mode
Transportation Mode
Vehicle body type
Engine type
Gearbox type

User interface

iOS

Integration

The Trip Simulator component includes two modules:

  • The first module is used as a testing tool for your debug application.

  • The second module is a “no-op” module. It will do nothing and does not include any trip data: it’s an empty implementation that mirrors the public methods and objects of the first module which can be integrated into your release-mode application to maintain a consistent codebase across both debug and release modes without embedding the real trip simulator in production.

To add the Trip Simulator module to your app, add the following lines to your dependencies in your Podfile, with the no-op module in release mode if you need it:

pod 'DriveKitTripSimulator', :configuration => ['Debug']
pod 'DriveKitTripSimulatorNoop', :configuration => ['Release']

Usage

DriveQuant offers the possibility of running simulations from a list of preset trips. After integrating and activating the trip simulation component, you can select a preset trip from those described in the table below. Once the simulation is launched, the Trip Analysis SDK will receive the configured callbacks automatically.

Name

Duration

Distance

Description

shortTrip

8 min

2 km

Trip too short that does not allow to rate the driver's behavior

mixedTrip

15 min

12 km

A 15-minute mixed trip in urban and suburban areas

cityTrip

20 min

8 km

A 20-minute city trip

suburbanTrip

30 min

30 km

A 30-minute trip performed in a suburban environment mostly

highwayTrip

55 min

100 km

A 55-minute highway trip

trainTrip

10 min

5 km

Trip recorded in a train to test the alternative transportation modes detection

busTrip

13 min

3 km

Trip recorded in a bus to test the alternative transportation modes detection

boatTrip

40 min

25 km

Trip recorded in a boat to test the alternative transportation modes detection

tripWithCrash

5 min

1 km

A trip to simulate an unconfirmed or a confirmed crash.

tripWithCrashStillDriving

23 min

24 km

A trip to simulate an accident confirmed less than two minutes after the start of the trip, after which the driver continued driving.

Check if it’s the no-op module

To verify if you are embedding the no-op module, you can call the following code:

let isNoop = DriveKitTripSimulator.shared.isNoop

Simulate a trip

To simulate a trip, you just need to send the selected trip to the start method:

import DriveKitTripSimulatorModule

DriveKitTripSimulator.shared.start(<The_PresetTrip_you_want>)

Stop the simulation

To stop the simulation of a trip, you need to call the stop method:

import DriveKitTripSimulatorModule

DriveKitTripSimulator.shared.stop()

Simulate a crash during a trip

The simulation of a trip with a collision only works on a real device, not with the simulator.

In order to mock a crash to check your integration, you must call the startCrashTrip function with a PresetCrashConfiguration item as parameter. Possible values for PresetCrashConfiguration enumeration are described in the table below:

Name
Description

confirmed30KmH

A short trip with a collision at 30 km/h that occurs 137 seconds after the trip begins and that corresponds to a confirmed accident.

confirmed20KmH

A short trip with a collision at 20 km/h that occurs 141 seconds after the trip begins and that corresponds to a confirmed accident.

confirmed10KmH

A short trip with a collision at 10 km/h that occurs 146 seconds after the trip begins and that corresponds to a confirmed accident.

unconfirmed0KmH

A short trip with a collision during a vehicle stop that occurs 159 seconds after the trip begins and that corresponds to an unconfirmed accident.

confirmed30KmHStillDriving

A trip to with a collision at 30km/h that occures 95 seconds after the trip begins and that corresponds to a confirmed accident, after which the driver continue driving.

DriveKitTripSimulator.shared.startCrashTrip(.confirmed20KmH)
Custom metadata
push crash data
Trip
TripResponseInfo
Trip
DeclaredTransportationMode
Trip
here
TripResult
Trip
here
TripResult
Trip
here
TripResult
here
Trip
here
TripResult
TripResult
TripResponseInfo
startTrip()
cancelTrip
cancelTrip
required
required
reset
reset
Vehicle body type
Engine type
Gearbox type
Drive wheels type
DriveKit Demo App
simulate a crash during a trip
here
ItineraryStatistics
BrakeWear
TireWear
EcoDriving
AdvancedEcoDriving
FuelEstimation
Advanced fuel estimation
Safety
AdvancedSafety
SafetyEvents
DriverDistraction
Pollutants
Speed Limit
SpeedLimitContexts
CallEvent
EnergyEstimation
AdvancedEnergyEstimation
ItineraryStatistics
BrakeWear
TireWear
EcoDriving
AdvancedEcoDriving
FuelEstimation
Advanced fuel estimation
Safety
AdvancedSafety
SafetyEvents
DriverDistraction
Pollutants
Speed Limit
SpeedLimitContexts
CallEvent
EnergyEstimation
AdvancedEnergyEstimation
disabled the SDK auto-initialization
CommonUI

Android

Introduction

DriveKit Common UI includes configuration options and resources that are shared by all DriveKit UI modules. It allows to configure the colors and fonts of all DriveKit UI modules.

If you use the DriveKit graphical libraries, it is mandatory to set the configurations with the Common UI module.

DriveKit Common UI has several benefits:

  • it includes reusable components,

  • it simplifies the standardization of all layouts,

  • it avoids code duplicates.

iOS

Android

iOS

Get started

Prerequisite

Integration

The Permissions Utils UI SDK is available on Cocoapods master repo.

To access the framework in the repository, add the following lines to your Podfile:

target 'my-target' do
  pod 'DriveKitPermissionsUtilsUI'
end

Then, run pod install

Initialization

import DriveKitPermissionsUtilsUI

Then, to initialize the Permissions Utils module in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate:

import DriveKitCoreModule
import DriveKitCommonUI
import DriveKitPermissionsUtilsUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   DriveKitUI.shared.initialize()
   DriveKitPermissionsUtilsUI.shared.initialize()
   ...
}

Android

Integration

The Trip Simulator component includes two modules:

  • The first module is used as a testing tool for your debug application.

  • The second module is a “no-op” module. It will do nothing and does not include any trip data: it’s an empty implementation that mirrors the public methods and objects of the first module which can be integrated into your release-mode application to maintain a consistent codebase across both debug and release modes without embedding the real trip simulator in production.

To include the Trip Simulator module in your app, insert the following lines into the dependencies section of your application's build.gradle file:

dependencies {
    debugImplementation 'com.drivequant.drivekit:drivekit-trip-simulator:$drivekit_version'
    releaseImplementation 'com.drivequant.drivekit:drivekit-trip-simulator-noop:$drivekit_version'
}

Replace $drivekit_version with the DriveKit version you are using in your app

Usage

DriveQuant offers the possibility of running simulations from a list of preset trips. After integrating and activating the trip simulation component, you can select a preset trip from those described in the table below. Once the simulation is launched, the Trip Analysis component will receive the configured callbacks automatically.

Name
Duration (min)
Distance (km)
Description

SHORT_TRIP

8

2

Trip too short that does not allow to rate the driver's behavior

MIXED_TRIP

15

12

A mixed trip in urban and suburban areas

CITY_TRIP

20

8

A city trip

SUBURBAN_TRIP

30

30

A trip performed in a suburban environment mostly

HIGHWAY_TRIP

55

100

A highway trip

TRAIN_TRIP

10

5

Trip recorded in a train to test the alternative transportation modes detection

BUS_TRIP

13

3

Trip recorded in a bus to test the alternative transportation modes detection

BOAT_TRIP

40

25

Trip recorded in a boat to test the alternative transportation modes detection

TRIP_WITH_CRASH_1

5

1

A trip to simulate an unconfirmed or a confirmed crash.

TRIP_WITH_CRASH_2_STILL_DRIVING

23

24

A trip to simulate an accident confirmed less than two minutes after the start of the trip, after which the driver continued driving.

Enable Developer Mode

Mock Location App

In the Debugging category, tap on Select mock location app and select yours. It sometimes appears that you might uninstall and reinstall your app on the device in order to register it as a mock location app.

Simulate a trip

To simulate a trip, call the following method with a appropriate configuration with the PresetTrip parameter.

fun start(presetTrip: PresetTrip, listener: DKTripSimulatorListener? = null): Boolean

Stop the simulation

To stop the trip simulation, you must call the following method:

fun stop()

Otherwise you can manually remove your app as the mock location app in the developers settings.

Simulate a crash during a trip

In order to mock an accident to check your integration, you must choose between TRIP_WITH_CRASH_1 or TRIP_WITH_CRASH_2_STILL_DRIVING as PresetTrip parameter:

Possible values for PresetTripCrash1 enum used by TRIP_WITH_CRASH_1 are described in the table below:

Name
Description

CONFIRMED_30KMH

A short trip with a collision at 30 km/h that occurs 137 seconds after the trip begins and that corresponds to a confirmed accident.

CONFIRMED_20KMH

A short trip with a collision at 20 km/h that occurs 141 seconds after the trip begins and that corresponds to a confirmed accident.

CONFIRMED_10KMH

A short trip with a collision at 10 km/h that occurs 146 seconds after the trip begins and that corresponds to a confirmed accident.

UNCONFIRMED_0KMH

A short trip with a collision during a vehicle stop that occurs 159 seconds after the trip begins and that corresponds to an unconfirmed accident.

DriveKitTripSimulator.start(PresetTrip.TRIP_WITH_CRASH_1(PresetTripCrash1.CONFIRMED_30KMH.CONFIRMED_30KMH))
DriveKitTripSimulator.INSTANCE.start(new PresetTrip.TRIP_WITH_CRASH_1(PresetTripCrash1.CONFIRMED_30KMH));

Check if it’s the no-op module

To check whether the "no-op" module is embedded, you can execute the following code:

val isNoop = DriveKitTripSimulator.isNoop
final boolean isNoop = DriveKitTripSimulator.INSTANCE.isNoop();

Main configurations

Permission management

On iOS, the user must grant access permission to the phone's location in background to enable the trip detection function included in the Trip Analysis component. There are several options for this permission and automatic mode will only work if the user selects the "Always" option.

The Permissions Utils component provides a set of screens to guide the user through the selection of the right options. Once the user has correctly authorized access to the location, you are warned by the closure passed in parameter:

DriveKitPermissionsUtilsUI.shared.getLocationPermissionViewController {
    // Code called when location permission is properly granted.
}

It is also recommended that the user allows access to activity recognition (aka "Motion and fitness"). The Permissions Utils component contains a dedicated screen to help the user:

DriveKitPermissionsUtilsUI.shared.getActivityPermissionViewController {
    // Code called when activity permission is properly granted.
}

The method below helps you to configure the required permission requests and the order in which they are displayed. You will be notified when the requested permissions are successfully granted:

DriveKitPermissionsUtilsUI.shared.showPermissionViews([.location, .activity], parentViewController: <UINavigationController>) {
    // Code called when permissions (here: "location" and "activity"), are both properly granted.
}

SDK diagnosis

Diagnosis screen areas

The diagnosis screen is divided into three areas:

  1. The first displays the status of sensors and permissions.

  2. The second contains a quick link to the battery optimization functions.

  3. The third displays a contact button to reach support.

The first two areas are always displayed. The third is optional.

The diagnosis function of the SDK has the following configurations:

  • In area 1, the sensors and permissions to be checked are selected automatically except for the Bluetooth sensor. If your application does not use a Bluetooth device or an iBeacon, it is not necessary to monitor the status of the Bluetooth sensor.

  • Area 2 is always displayed. If battery optimization is enabled, a link will appear to redirect the user to the phone settings. The user will have to open the battery settings to disable the optimization.

  • In area 3, it is possible to configure the recipient's email address for the support request or a web address to which the user can be directed.

Bluetooth sensor status check

Access to the Bluetooth sensor is not required on iOS. This permission is not requested when the application is first installed.

For natural triggering (i.e. from the phone's sensors), or using an iBeacon, Bluetooth access is not required.

Access to the Bluetooth sensor is required in the two cases described below:

  1. To enable automatic start of trip recording from a Bluetooth device.

  2. To measure the battery level of an iBeacon device.

Support Request Management

The user can make a support request if the application does not work properly.

When the user clicks on the support request button, you can choose between two actions:

  1. An email will be automatically composed,

  2. or a redirection to a web page of your choice will be made.

The email contains the key information to ease the diagnosis of a problem (status of permissions and phone sensors). The recipient's email is configurable, as well as other parameters:

import DriveKitCoreModule
import DriveKitCommonUI
import DriveKitPermissionsUtilsUI

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      DriveKitUI.shared.initialize()
      DriveKitPermissionsUtilsUI.shared.initialize()
      ...
      DriveKitPermissionsUtilsUI.shared.configureContactType(
         DKContactType.email(MailConfiguration())
      )
   }
}

class MailConfiguration: DKContentMail {
    func getRecipients() -> [String] {
        ["support@company.com"]
    }

    func getBccRecipients() -> [String] {
        []
    }

    func getSubject() -> String {
        "[App] Technical support request"
    }

    func getMailBody() -> String {
        ""
    }

    func overrideMailBodyContent() -> Bool {
        false
    }
}

If you don’t want the email body to contain information about the state of permissions and sensors, then return “true” in the method “overrideMailBodyContent()”.

If you want to redirect the user to a web page instead of composing an email, you have to add the following line:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   DriveKitUI.shared.initialize()
   DriveKitPermissionsUtilsUI.shared.initialize()
   ...
   DriveKitPermissionsUtilsUI.shared.configureContactType(DKContactType.web(<url>))
}

In this specific case, there is no way to obtain information about authorization and sensor status.

If you do not configure the contact type, this area will be hidden and will not appear on the diagnosis screen.

Android 15 Migration guide

1 - Check major changes

It is necessary to read this documentation before modifying any code in your project.

You must consider the two main categories of behaviours changes related to Android 15:

2 - Targeting Android 15 in your project

To make your app fully compatible with Android 15, update the targetSdkVersion and compileSdkVersion to 35 in your project app.

3 - Apply changes

It's now time to update your code once the previous steps are taken into account.

4 - Update the DriveKit SDK

After you have checked that your project is working properly and updated the targetSdkVersion and compileSdkVersion, you need to update the DriveKit SDK.

  • DriveKit internal modules that support Android 15 are versions 2.4.0 and above.

  • DriveKit UI modules that support Android 15 are versions 2.4.0 and above.

The latest DriveKit versions are listed in the changelog:

5 - Tests 🚗

Trip

This section describes the trip analysis API.

Description

The overall approach behind DriveQuant’s trip analysis service is based on vehicle dynamics and powertrain modeling. Using vehicle or smartphone sensors, our services estimate the efforts applied to the powertrain enabling us, for example, to remodel the efforts between the road and the wheels or to estimate the exhaust pollutants.

DriveQuant’s data analysis service delivers a wide range of indicators describing vehicle usage and driver behavior. For a single trip, DriveQuant’s trip analysis service retrieves:

  1. eco-driving indicators,

  2. an estimate of the fuel consumption,

  3. safety indicators,

  4. tire and brake wear measurements,

  5. pollutant emissions estimation,

  6. a distraction score (phone use),

  7. and a speed limit score.

The trip analysis API is automatically requested by the DriveKit SDK at the end of each trip.

This API can also be used without the DriveKit SDK if you have your own GPS data collection system (OBD dongle, black box, vehicle data).

The distraction score (phone use) is only available for SDK users.

An additional cost is required for the use of the speed limit score, which is calculated using data coming from map data providers.

This section explains how to query the trip analysis API, how driving indicators are computed and how they are structured.

Trip

POST https://service.drivequant.com/v2/trip

This method returns all driving analytics calculated by DriveQuant for a trip.

Request Body

Name
Type
Description

account

object

Identification data for the trip

route

object

GPS or vehicle recorded data for the trip

vehicle

object

Vehicle characteristics used for the trip

itineraryData

object

Data of the trip

metaData

object

Customer specific data

  {
    "status": true,
    "itinId": "6030ebe4ea60426b34e9b3bf",
    "userId": "<UNIQUE USER OR ASSET ID>",
    "comments": [{
      "errorCode": 16,
      "comment": "Engine speed not available"
      },
      {
        "errorCode": 0,
        "comment": "OK"
      }
    ],
    "itineraryStatistics": {
        "tripDuration": 1996.0,
        "drivingDuration": 1737.0,
        "idlingDuration": 259.0,
        "drivingPercentage": 87.0,
        "idlingPercentage": 13.0,
        "distance": 15801.0,
        "speedMean": 30.5,
        "subdispNb": 60,
        "meteo": 2,
        "day": true,
        "weekDay": false,
        "transportationMode": 1
    },
    "ecoDriving": {
        "score": 7.1,
        "scoreAccel": -1.7,
        "scoreMain": 0.9,
        "scoreDecel": -0.5,
        "stdDevAccel": 2.2006383,
        "stdDevMain": 0.99105114,
        "stdDevDecel": 3.797757,
        "energyClass": 2
    },
    "fuelEstimation": {
        "co2Mass": 2.691,
        "co2Emission": 170.0,
        "fuelVolume": 1.153,
        "fuelConsumption": 7.3,
        "idleFuelVolume": 0.049,
        "idleFuelPercentage": 4.28,
        "idleFuelConsumption": 0.696,
        "idleCo2Emission": 1.625,
        "idleCo2Mass": 0.115,
        "engineTempStatus": true,
        "coldFuelVolume": 0.018
    },
    "safety": {
        "safetyScore": 9.1,
        "nbAdh": 2,
        "nbAccel": 0,
        "nbDecel": 3,
        "nbAdhCrit": 0,
        "nbAccelCrit": 0,
        "nbDecelCrit": 1
    },
    "advancedEcoDriving": {
        "ecoDrivingContext": [
            {
                "contextId": 0,
                "distance": 6.9,
                "duration": 19.1,
                "efficiencyScore": 11.0,
                "scoreAccel": 6.0,
                "scoreMain": 6.0,
                "scoreDecel": 6.0
            },
            {
                "contextId": 1,
                "distance": 3.7,
                "duration": 6.5,
                "efficiencyScore": 6.1,
                "scoreAccel": -2.8,
                "scoreMain": 0.3,
                "scoreDecel": 1.3
            },
            {
                "contextId": 2,
                "distance": 64.8,
                "duration": 61.8,
                "efficiencyScore": 6.7,
                "scoreAccel": -1.7,
                "scoreMain": 0.6,
                "scoreDecel": -1.3
            },
            {
                "contextId": 3,
                "distance": 12.7,
                "duration": 7.8,
                "efficiencyScore": 6.6,
                "scoreAccel": -1.8,
                "scoreMain": 1.6,
                "scoreDecel": 0.8
            },
            {
                "contextId": 4,
                "distance": 11.8,
                "duration": 4.9,
                "efficiencyScore": 8.4,
                "scoreAccel": -1.1,
                "scoreMain": 0.1,
                "scoreDecel": -2.9
            }
        ]
    },
    "advancedFuelEstimation": {
        "fuelEstimationContext": [
            {
                "contextId": 0,
                "distance": 6.9,
                "duration": 19.1,
                "co2Mass": 0.199,
                "co2Emission": 179.0,
                "fuelVolume": 0.085,
                "fuelConsumption": 7.69
            },
            {
                "contextId": 1,
                "distance": 3.7,
                "duration": 6.5,
                "co2Mass": 0.099,
                "co2Emission": 167.0,
                "fuelVolume": 0.042,
                "fuelConsumption": 7.139
            },
            {
                "contextId": 2,
                "distance": 64.8,
                "duration": 61.8,
                "co2Mass": 1.832,
                "co2Emission": 176.0,
                "fuelVolume": 0.785,
                "fuelConsumption": 7.535
            },
            {
                "contextId": 3,
                "distance": 12.7,
                "duration": 7.8,
                "co2Mass": 0.264,
                "co2Emission": 130.0,
                "fuelVolume": 0.113,
                "fuelConsumption": 5.549
            },
            {
                "contextId": 4,
                "distance": 11.8,
                "duration": 4.9,
                "co2Mass": 0.182,
                "co2Emission": 96.0,
                "fuelVolume": 0.078,
                "fuelConsumption": 4.107
            }
        ]
    },
    "advancedSafety": {
        "safetyContext": [
            {
                "contextId": 0,
                "distance": 6.9,
                "duration": 19.1,
                "nbAdh": 0,
                "nbAccel": 0,
                "nbDecel": 0,
                "nbAdhCrit": 0,
                "nbAccelCrit": 0,
                "nbDecelCrit": 0,
                "safetyScore": 11.0
            },
            {
                "contextId": 1,
                "distance": 3.7,
                "duration": 6.5,
                "nbAdh": 0,
                "nbAccel": 0,
                "nbDecel": 0,
                "nbAdhCrit": 0,
                "nbAccelCrit": 0,
                "nbDecelCrit": 0,
                "safetyScore": 11.0
            },
            {
                "contextId": 2,
                "distance": 64.8,
                "duration": 61.8,
                "nbAdh": 2,
                "nbAccel": 0,
                "nbDecel": 2,
                "nbAdhCrit": 0,
                "nbAccelCrit": 0,
                "nbDecelCrit": 1,
                "safetyScore": 9.1
            },
            {
                "contextId": 3,
                "distance": 12.7,
                "duration": 7.8,
                "nbAdh": 0,
                "nbAccel": 0,
                "nbDecel": 0,
                "nbAdhCrit": 0,
                "nbAccelCrit": 0,
                "nbDecelCrit": 0,
                "safetyScore": 10.0
            },
            {
                "contextId": 4,
                "distance": 11.8,
                "duration": 4.9,
                "nbAdh": 0,
                "nbAccel": 0,
                "nbDecel": 1,
                "nbAdhCrit": 0,
                "nbAccelCrit": 0,
                "nbDecelCrit": 0,
                "safetyScore": 8.0
            }
        ]
    },
    "pollutants": {
        "co": 436.34,
        "hc": 105.19,
        "nox": 43.45,
        "soot": 0.01
    },
    "tireWear": {
        "frontTireWear": 625151,
        "rearTireWear": 194424,
        "frontTireDistance": 6522,
        "rearTireDistance": 6522,
        "frontTireAutonomy": 25010,
        "rearTireAutonomy": 159958,
        "frontTireTotalWear": 20.6847961834131,
        "rearTireTotalWear": 3.917838643900801,
        "frontTireWearRate": 3.1593584519985076,
        "rearTireWearRate": 0.5879650354629268
    },
    "brakeWear": {
        "frontBrakePadWear": 652316,
        "rearBrakePadWear": 490585,
        "frontBrakeDistance": 6522,
        "rearBrakeDistance": 6522,
        "frontBrakeAutonomy": 51081,
        "rearBrakeAutonomy": 70712,
        "frontBrakeTotalWear": 11.322879923360654,
        "rearBrakeTotalWear": 8.444911708095175,
        "frontBrakeWearRate": 1.6040543118399773,
        "rearBrakeWearRate": 1.1953688298028098
    },
    "safetyEvents": [
        {
            "time": 198.0,
            "longitude": 2.2345499992370605,
            "latitude": 48.865421295166016,
            "velocity": 27.597404310389447,
            "heading": 181.3752105740906,
            "elevation": 21.428831625626,
            "distance": 1803.0,
            "type": 3,
            "level": 1,
            "value": -1.9984114049011923
        },
        {
            "time": 886.0,
            "longitude": 2.228440046310425,
            "latitude": 48.829158782958984,
            "velocity": 9.322159013829488,
            "heading": 115.71003406053404,
            "elevation": 35.0165024497636,
            "distance": 5811.0,
            "type": 1,
            "level": 1,
            "value": 0.2091391662960067
        },
        {
            "time": 1179.0,
            "longitude": 2.2220299243927,
            "latitude": 48.776981353759766,
            "velocity": 59.56077714321047,
            "heading": 196.14873235105892,
            "elevation": 169.4896656907427,
            "distance": 8721.0,
            "type": 3,
            "level": 1,
            "value": -1.851640380003413
        },
        {
            "time": 1352.0,
            "longitude": 2.2241098880767822,
            "latitude": 48.76197814941406,
            "velocity": 23.478607191677995,
            "heading": 231.66262821151452,
            "elevation": 96.56055945085538,
            "distance": 11036.0,
            "type": 1,
            "level": 1,
            "value": 0.2596086644093922
        },
        {
            "time": 1352.0,
            "longitude": 2.2241098880767822,
            "latitude": 48.76197814941406,
            "velocity": 23.478607191677995,
            "heading": 231.66262821151452,
            "elevation": 96.56055945085538,
            "distance": 11036.0,
            "type": 3,
            "level": 2,
            "value": -3.1478373502646355
        },
        {
            "time": 1902.0,
            "longitude": 2.2364699840545654,
            "latitude": 48.742130279541016,
            "velocity": 29.11161620369841,
            "heading": 127.70357513427746,
            "elevation": 76.72611043725985,
            "distance": 14436.0,
            "type": 3,
            "level": 1,
            "value": -2.095731316728654
        }
    ],
    "endDate": "2021-02-20T10:56:37.188+0000",
    "itineraryData": {
        "endDate": "2021-02-20T10:56:37.188+0000",
        "startDate": "2021-02-20T10:23:22.188+0000",
        "departureCity": "<DEPARTURE>",
        "arrivalCity": "<ARRIVAL>",
        "departureAddress": "<DEPARTURE ADDRESS>",
        "arrivalAddress": "<ARRIVAL ADDRESS>"
    },
    "driverDistraction": {
        "nbUnlock": 1,
        "durationUnlock": 97.0,
        "durationPercentUnlock": 4.86002640172576,
        "distanceUnlock": 403.68833585416337,
        "distancePercentUnlock": 2.5548277694713204,
        "score": 1.9159997325752993,
        "scoreUnlock": 6.7627283707197705,
        "scoreCall": 1.9159997325752993,
        "calls": [
            {
                "id": 0,
                "start": 544.0035407543182,
                "end": 634.0030286312103,
                "durationS": 89,
                "duration": 5,
                "distanceM": 456,
                "distance": 3,
                "status": "OUTGOING",
                "audioSystem": "SPEAKER",
                "forbidden": true
            }
        ]
    },
    "distractionEvents": [
        {
            "time": 539.0,
            "latitude": 48.85495,
            "longitude": 2.22616,
            "velocity": 12.168000411987304,
            "heading": -1.616703658463509,
            "elevation": 23.05337370577991,
            "distance": 3245.3746307904125,
            "type": 1,
            "duration": 97,
            "index": 539
        },
        {
            "time": 636.0,
            "latitude": 48.85034,
            "longitude": 2.22683,
            "velocity": 45.22616824022174,
            "heading": -1.3488582653419061,
            "elevation": 29.8860134067469,
            "distance": 3746.5653789286157,
            "type": 2,
            "duration": 1360,
            "index": 636
        }
    ],
    "callEvents": [
        {
            "time": 544.0035407543182,
            "latitude": 48.85475,
            "longitude": 2.22616,
            "velocity": 12.456000137329102,
            "heading": -1.5768984084633124,
            "elevation": 23.53374615925395,
            "distance": 0.0,
            "type": 3,
            "duration": 1,
            "index": 544,
            "audioSystem": "SPEAKER",
            "callType": "OUTGOING",
            "forbidden": true
        },
        {
            "time": 634.0030286312103,
            "latitude": 48.85059,
            "longitude": 2.22674,
            "velocity": 46.44316055270816,
            "heading": -1.3482454261409265,
            "elevation": 30.170426377189013,
            "distance": 456.0,
            "type": 4,
            "duration": 89,
            "index": 634,
            "audioSystem": "SPEAKER",
            "callType": "OUTGOING",
            "forbidden": true
        }
    ],
    "speedingEvents": [
        {
            "longitude": 2.240690719770278,
            "latitude": 48.87119316290749,
            "time": 96.0,
            "type": 1,
            "index": 36
        },
        {
            "longitude": 2.2389993413999454,
            "latitude": 48.87022711541927,
            "time": 106.0,
            "type": 0,
            "index": 39
        },
        {
            "longitude": 2.226948759849819,
            "latitude": 48.8285248546614,
            "time": 899.0,
            "type": 1,
            "index": 220
        },
        {
            "longitude": 2.2247798257606703,
            "latitude": 48.82771252373621,
            "time": 910.0,
            "type": 0,
            "index": 229
        },
        {
            "longitude": 2.220820796904408,
            "latitude": 48.790306020720436,
            "time": 1121.87393116951,
            "type": 1,
            "index": 374
        },
        {
            "longitude": 2.222806342988146,
            "latitude": 48.781090574187054,
            "time": 1158.87393116951,
            "type": 0,
            "index": 409
        },
        {
            "longitude": 2.221726988867627,
            "latitude": 48.776698917142845,
            "time": 1181.87393116951,
            "type": 1,
            "index": 428
        },
        {
            "longitude": 2.221415682498137,
            "latitude": 48.77728241347195,
            "time": 1198.87393116951,
            "type": 0,
            "index": 449
        },
        {
            "longitude": 2.2259807317602576,
            "latitude": 48.77630605611952,
            "time": 1222.87393116951,
            "type": 1,
            "index": 472
        },
        {
            "longitude": 2.229023362169593,
            "latitude": 48.77273423930304,
            "time": 1252.87393116951,
            "type": 0,
            "index": 499
        },
        {
            "longitude": 2.2291619672238197,
            "latitude": 48.77164365290039,
            "time": 1259.87393116951,
            "type": 1,
            "index": 502
        },
        {
            "longitude": 2.229596580809962,
            "latitude": 48.76831710988511,
            "time": 1281.87393116951,
            "type": 0,
            "index": 525
        }
    ],
    "speedingStatistics": {
        "distance": 15857,
        "duration": 1727,
        "speedingDistance": 1956,
        "speedingDuration": 105,
        "score": 4.82,
        "speedLimitContexts": [
            {
                "speedLimit": 30,
                "distance": 966,
                "duration": 138,
                "speedingDistance": 188,
                "speedingDuration": 16,
                "score": 1.09
            },
            {
                "speedLimit": 50,
                "distance": 11115,
                "duration": 1367,
                "speedingDistance": 1112,
                "speedingDuration": 65,
                "score": 3.0
            },
            {
                "speedLimit": 70,
                "distance": 1504,
                "duration": 95,
                "speedingDistance": 0,
                "speedingDuration": 0,
                "score": 10.0
            },
            {
                "speedLimit": 80,
                "distance": 655,
                "duration": 62,
                "speedingDistance": 0,
                "speedingDuration": 0,
                "score": 10.0
            },
            {
                "speedLimit": 90,
                "distance": 1617,
                "duration": 65,
                "speedingDistance": 656,
                "speedingDuration": 24,
                "score": 0.0
            }
        ]
    },
    "energyEstimation":{
    "energy": 0.0,
    "energyConsumption": 0.0,
    "energyOpti": 0.0,
    "energyOptiConsumption": 0.0
  },
  "advancedEnergyEstimation": [
    {
      "contextId": 0,
      "distance": 6.9,
      "duration": 19.1,
      "energy": 0.0,
      "energyConsumption": 0.0,
      "energyOpti": 0.0,
      "energyOptiConsumption": 0.0
    },
    {
      "contextId": 1,
      "distance": 3.7,
      "duration": 6.5,
      "energy": 0.0,
      "energyConsumption": 0.0,
      "energyOpti": 0.0,
      "energyOptiConsumption": 0.0
    },
    {
      "contextId": 2,
      "distance": 64.8,
      "duration": 61.8,
      "energy": 0.0,
      "energyConsumption": 0.0,
      "energyOpti": 0.0,
      "energyOptiConsumption": 0.0
    },
    {
      "contextId": 3,
      "distance": 12.7,
      "duration": 7.8,
      "energy": 0.0,
      "energyConsumption": 0.0,
      "energyOpti": 0.0,
      "energyOptiConsumption": 0.0
    },
    {
      "contextId": 4,
      "distance": 11.8,
      "duration": 4.9,
      "energy": 0.0,
      "energyConsumption": 0.0,
      "energyOpti": 0.0,
      "energyOptiConsumption": 0.0
    }
  ]
  }

Request

Account

Field
Type
Description

account

string

API key

userId

string

User unique identifier

vehicleId

string

Vehicle unique identifier

DriveQuant counts the number of active assets per customer. The DriveQuant API is a pay-per-active-asset API. An asset is considered active if it has performed at least one trip on a monthly basis. An asset can be a driver (identified with its driverId) or a vehicle (identified by a vehicleId).

Three main use cases can be considered:

  1. The request includes only a driverId: This is common when the data collected comes from a mobile application installed on a driver's phone. The total number of assets per customer is equal to the number of unique driverId's.

  2. The request includes only a vehicleId: This is common when the data collected comes from a telematics device plugged into the vehicle. The total number of assets per customer is equal to the number of unique vehicleId's.

The Account object must contain the account and the userId or vehicleId attributes.

Route

Field
Type
Description

gpsVelocity

array[double]

GPS speed vector in km/h

latitude

array[double]

Latitude vector in degree

longitude

array[double]

Longitude vector in degree

gpsAccuracy

array[double]

GPS accuracy vector in meter

gpsElevation

array[double]

Elevation vector in meter

gpsHeading

array[double]

Heading vector in degree

gpsDate

array[double]

GPS timestamp vector in second

vehVelocity

array[double]

Vehicle speed vector in km/h

vehEngineSpeed

array[double]

Engine speed vector in rotation per minute

vehTankLevel

array[double]

Fuel tank volume in liter

vehWheelAngle

array[double]

Steering angle vector in degree

batteryVoltage

array[double]

Measurement of the car battery voltage vector in volt

vehDate

array[double]

Vehicle date timestamp vector in second

  • A request must contain all the data corresponding to a single trip. The trip data analysis cannot be cut into multiple queries. It is not recommended to merge data from several trips into a single request.

  • Route object must contain at least the vehDate or gpsDate and at least gpsVelocity or vehVelocity attributes.

  • The input variables included into Route object are arrays which must contain the same number of data points.

Vehicle

Field
Type
Description

carTypeIndex

int

carEngineIndex

int

carPower

double

carMass

double

Vehicle mass in kg

carGearboxIndex

int

carConsumption

double

Combined fuel consumption [l/100km] measured during the New European Driving Cycle (NEDC)

carAutoGearboxNumber

int

Number of gear ratios for the automatic gearbox. This parameter is taken into account only if carGearboxIndex is set to 1

Some parameters have a default value if not set, and a min and max limitations:

Field
Default value
Min
Max

carTypeIndex

1 (compact)

-

-

carEngineIndex

1 (gasoline)

-

-

carPower

150

40

450

carMass

1400

700

3500

carGearboxIndex

2 (manual 5-speed)

-

-

carConsumption

4.5

3

20

ItineraryData

Itinerary object is optional.

Field
Type
Description

startDate

date

Trip start date

Date format: YYYY-MM-dd’T’HH:mm:ss.SSSZ

endDate

date

Trip end date Date format: YYYY-MM-dd’T’HH:mm:ss.SSSZ

departureCity

string

Name of the departure city

arrivalCity

string

Name of the arrival city

MetaData

Metadata can be used if you want to add some of your specific data in a trip. They can be added to the Trip API as a key/value object where the key and value have a String type

Example of JSON body request

{
	"account": {
		"account": "<API KEY>",
		"userId": "<UNIQUE USER ID>",
		"vehicleId": "<UNIQUE VEHICLE ID>" 
	},
	"vehicle": {
		"carTypeIndex": 4,
		"carEngineIndex": 1,
		"carPower": 205.0,
		"carMass": 1430.0,
		"engineDisplacement": 1618.0,
		"carGearboxIndex": 2,
		"carConsumption": 6.0
	},
	"itineraryData": {
    "startDate": "2018-02-15T15:20:00.000+0200",
		"endDate": "2018-02-15T15:50:00.000+0200",
		"departureCity": "<DEPARTURE>",
		"arrivalCity": "<ARRIVAL>"
	},
	"route": {
		"gpsVelocity": [...],
		"latitude": [...],
		"longitude": [...],
		"gpsHeading": [...],
		"gpsElevation": [...],
		"gpsDate": [...],
		"gpsAccuracy": [...]
	},
	"metaData" : {
		"customerStringData" : "<CUSTOMER STRING DATA>",
		"customerJsonData" : "{\"customerTestNumber\" : 1, \"customerTestString\" : \"<CUSTOMER TEXT>\"}"
  }
}

Response

The table below summarizes the list of driving data analysis modules. The comments and itinerary statistics modules are included by default. All other modules are optional and can be combined as needed.

Field
Type
Description

itinId

string

Trip unique identifier

status

boolean

true if no problem, false otherwise

comments

array[object]

itineraryStatistics

object

itineraryData

object

ecoDriving

object

advancedEcoDriving

object

fuelEstimation

object

advancedFuelEstimation

object

safety

object

advancedSafety

object

safetyEvents

array[object]

tireWear

object

brakeWear

object

pollutants

object

userId

string

unique id of the user

firstname

string

first name of the user

lastname

string

Last name of the user

endDate

string

End date of the trip

driverDistraction

object

distractionEvents

array[object]

callEvents

array[object]

speedingStatistics

object

speedingEvents

array[object]

energyEstimation

object

advancedEnergyEstimation

array[object]

Comment

Field
Type
Description

errorCode

int

Error code

comment

string

Error description

ItineraryStatistics

Itinerary Statistics module provides several indicators that characterize the trip conditions: the trip distance, the vehicle movement duration and the idle duration. We also compute the number of sub-displacements. A trip can be characterized as a succession of events either dictated by the driver’s will or by external factors. These events, called breakpoints, are indicated with black dots in the figure below. Each section of a trip between two breakpoints is called sub-displacement. The figure illustrates these concepts for a short trip with one traffic light (vehicle stopped) and one intersection with priority (vehicle deceleration followed by acceleration).

Field
Type
Description

distance

double

Distance travelled in meter

speedMean

double

Mean vehicle speed in km/h

tripDuration

double

Total trip duration in second

drivingDuration

double

Vehicle movement duration in second

idlingDuration

double

Total duration of idling phases (vehicle stopped)

in second

drivingPercentage

double

Percentage of vehicle movement

idlingPercentage

double

Percentage of idling phases

subdispNb

int

Number of sub-displacements detected during the trip

meteo

int

day

boolean

true if day, false if night

weekDay

boolean

true: Monday to Friday, false: Saturday to Sunday

transportationMode

int

ItineraryData

Field
Type
Description

startDate

date

Trip start date Date format: YYYY-MM-dd’T’HH:mm:ss.SSSZ

endDate

date

Trip end date Date format: YYYY-MM-dd’T’HH:mm:ss.SSSZ

departureCity

string

Name of the departure city

arrivalCity

string

Name of the arrival city

departureAddress

string

Departure full address

arrivalAddress

string

Arrival full address

Eco-driving

Description

Eco-driving module performs an analysis of the entire trip, characterized by a succession of events and road segments. The driving efficiency is computed by comparing the vehicle speed recorded with an optimal speed profile, for each segment. This calculation takes into account the actual driving conditions and a physical vehicle model that captures the inertial dynamics of the vehicle and the efficiency of the powertrain components. The eco-driving score ranges from 0 and 10, and is calculated by comparing the actual energy consumed during the trip with the energy that would have been consumed using the optimal speed profile. The best eco-driving score corresponds to the highest driving efficiency.

Field
Type
Description

score

double

Eco-driving score (min: 0, max: 10). If trip is too short to be scored, score is set to 11.

scoreAccel

double

Score of the acceleration phases. If trip is too short to be scored, score is set to 6.

scoreMain

double

Score of the stabilized speed phases. If trip is too short to be scored, score is set to 6.

scoreDecel

double

Score of the deceleration phases. If trip is too short to be scored, score is set to 6.

stdDevAccel

double

Standard deviation of acceleration score

stdDevMain

double

Standard deviation of stabilized speed score

stdDevDecel

double

Standard deviation of deceleration score

energyClass

int

0: energy class A

1: energy class B

2: energy class C

3: energy class D

4: energy class E

Scores definitions

Acceleration, deceleration and speed maintain phases have a large impact on the vehicle’s fuel consumption. As a consequence, by comparing the real and the optimal speed profiles, eco-driving analysis module returns 3 key driving indicators.

The acceleration and deceleration scores range from -5 to +5. For a value of (-5), your acceleration or deceleration is too slow. For the highest value (+5) you are accelerating or decelerating too fast. A score of (0) indicates that your acceleration or deceleration perfectly matches with an eco-driving style.

The speed maintain score ranges from 0 to 5. The minimum value (0) indicates that the driver has an appropriate behavior and drives at a constant speed. On the other hand, if the driving analysis module detects an oscillating speed profile, this score increases. The highest value (+5) indicates that you can improve to keep a constant speed to reduce your fuel consumption.

These indicators will help you improve your driving efficiency and reduce your energy consumption. They can also illustrate the level of anticipation that the drivers should adopt to avoid harsh accelerations and brakings.

The numerical values of driving scores can be transformed into driving tips. The tables below give examples of content that can be returned to a driver based on the driving notes of a trip:

scoreAccel
Description

-5 to -4

Acceleration is too low

-4 to -2

Weak acceleration

-2 to 1

Good acceleration

1 to 3

Strong acceleration

3 to 5

Acceleration is too high

scoreMain
Description

0 to 1.5

Good speed maintain

1.5 to 3.5

Irregular speed

3.5 to 5

Very fluctuating speed

scoreDecel
Description

-5 to -4

Deceleration is too low

-4 to -2

Weak deceleration

-2 to 1

Good deceleration

1 to 3

Strong deceleration

3 to 5

Deceleration is too high

The eco-driving analysis is performed for vehicle displacement greater than 100 meters and speed higher than 10 km/h. This avoids providing inaccurate driving scores during vehicle maneuvers (slow driving in traffic jams or in parking lots...). In that case, eco-driving analysis module returns the following error codes:

  • 11 for the eco-driving score

  • 6 for acceleration phase, stabilized speed phase and deceleration phase

Energy class

The energy class « energyClass » depends on the average fuel consumption of the vehicle. It positions the trip fuel consumption with respect to the average consumption of the vehicle.

  • Class A corresponds to 0.5 x the NEDC consumption of the vehicle expressed in gCO2/km\mathrm{gCO_2/km}gCO2​/km.

  • Class E corresponds to 1.5 x the NEDC consumption of the vehicle expressed in gCO2/km\mathrm{gCO_2/km}gCO2​/km

Then we defined the 5 classes with a uniform distribution between class A and class E. The energy class « energyClass » is calculated from the trip CO2\mathrm{CO_2}CO2​ emission « co2Emission » and the function below:

Advanced eco-driving

Field
Type
Description

ecoDrivingContext

array[object]

In order to provide fair scoring and to facilitate drivers comparison, the trip scores can be accompanied by road class scores. These scores are included in the EcoDrivingContext class into the Advanced Modules. This service differentiates 5 types of road conditions (contextId) to contextualize the driving scores:

  • 0 - Traffic jam: This corresponds to vehicle displacements of less than 100 meters and performed with speeds below 10 km/h. In traffic jams, it is obviously not possible to improve your driving, that is why scoring are not provided for this type of road.

  • 1 - Heavy urban traffic

  • 2 - City

  • 3 - Suburban

  • 4 - Expressways

In case a road type is not included in the trip, the distance and duration percentages are equal to zero, the efficiency score is set to 11 and the driving scores (Accel/Main/Decel) are set to 6.

EcoDrivingContext

Field
Type
Description

distance

double

Percentage of distance travelled in a road type

duration

double

Percentage of elapsed time in a road type

efficiencyScore

double

Eco-driving score

scoreAccel

double

Score of the acceleration phases

scoreMain

double

Score of the stabilized speed phases

scoreDecel

double

Score of the deceleration phases

contextId

int

Fuel estimation

Description

The fuel consumption is obtained from a backward computation based on a mathematical modeling of the vehicle and powertrain. Fuel consumption estimation asseses the mechanical traction power from the vehicle speed and mass. A power transfer is performed between each component of the powertrain to compute the engine torque. Finally, the engine torque combined with the vehicle speed help to process the fuel mass from an engine consumption map developed by IFPEN. This fuel mapping is adapted according to the vehicle parameters and is valid for any type of vehicle or fleet of vehicles.

This approach is particularly adapted to estimate real-driving fuel consumption which can be more than 20% above the homologation data provided by car manufacturers. The main advantage lies in the accuracy of the estimate that can reach 5% when all input variables are available and the vehicle parameters set. The estimation method accounts for the physical fuel characteristics. These parameters are listed below:

Fuel type
Density (kg/l)
Lower heating value (GJ/t)
CO2 emission factor (tCO2/TJ)
CO2 emission factor (kgCO2/l)

Gasoline

0.755

44

70.26

2.3340

Diesel

0.845

42

75.70

2.6866

Values calculated by fuel estimation module are described below:

Field
Type
Description

co2Mass

double

co2Emission

double

fuelConsumption

double

Average fuel consumption per unit of distance in l/100km

fuelVolume

double

Total fuel consumption in liter

idleFuelPercentage

double

Idle fuel consumption percentage

idleFuelConsumption

double

Idle fuel consumption per unit of time in l/h

idleCo2Emission

double

idleCo2Mass

double

engineTempStatus

boolean

Engine cold start?

coldFuelVolume

double

Cold engine fuel volume

Advanced fuel estimation

Field
Type
Description

fuelEstimationContext

array[object]

In order to provide detailed fuel consumption estimation across the vehicle trips, the advanced fuel estimation service may return the fuel consumption for each driving context of the vehicle. This service differentiates 5 types of road conditions (contextId):

  • 0 - Traffic jam

  • 1 - Heavy urban traffic

  • 2 - City

  • 3 - Suburban

  • 4 - Expressways

In case a road type is not included in the trip, the percentages of distance and duration are equals to zero as well as the co2Mass, co2Emission, fuelVolume and fuelConsumption.

FuelEstimationContext

Field
Type
Description

contextId

int

Road conditions

distance

double

Percentage of distance travelled in a road type

duration

double

Percentage of elapsed time in a road type

co2Mass

double

co2Emission

double

fuelVolume

double

Total fuel consumption in liter

fuelConsumption

double

Average fuel consumption in l/100km

EnergyEstimation

For electric vehicles, DriveQuant provides energy information instead of fuel estimation.

Field
Type
Description

energy

double

Estimated energy in kWh

energyConsumption

double

Estimated energy consumption in kWh/100km

energyOpti

double

Optimal energy in kWh

energyOptiConsumption

double

Optimal energy consumption in kWh/100km

The EnergyEstimation sub-document is only present in the response body for electric vehicles. If the configured vehicle is a conventional vehicle, the energy estimation is not added in the response body.

AdvancedEnergyEstimation

To provide more details on the energy consumption, the service may return the energy data for each driving context of the vehicle.

Field
Type
Description

energy

double

Estimated energy in kWh

energyConsumption

double

Estimated energy consumption in kWh/100km

energyOpti

double

Optimal energy in kWh

energyOptiConsumption

double

Optimal energy in kWh/100km

contextId

int

Road conditions

distance

double

Percentage of distance travelled in a road type

duration

double

Percentage of elapsed time in a road type

The AdvancedEnergyEstimation sub-document is only present in the response body for electric vehicles. If the configured vehicle is a conventional vehicle, the energy estimation is not added in the response body.

Safety

Field
Type
Description

safetyScore

double

Driver risk index for a given itinerary

Ranges from 3 to 10

nbAdh

int

Number of adherence threshold crossing

nbAccel

int

Number of strong accelerations

nbDecel

int

Number of strong decelerations

nbAdhCrit

int

Number of adherence threshold crossing (critical)

nbAccelCrit

int

Number of critical accelerations (critical)

nbDecelCrit

int

Number of critical decelerations (critical)

If trip is too short to be scored, safetyScore is set to 11.

Advanced safety

Field
Type
Description

safetyContext

array[object]

SafetyContext

Field
Type
Percentage of distance travelled in a road type

distance

double

Percentage of distance travelled in a road type

duration

double

Percentage of elapsed time in a road type

safetyScore

double

Ranges from 3 to 10

nbAdh

int

Number of adherence threshold crossing

nbAccel

int

Number of strong accelerations

nbDecel

int

Number of strong decelerations

nbAdhCrit

int

Number of adherence threshold crossing (critical)

nbAccelCrit

int

Number of critical accelerations (critical)

nbDecelCrit

int

Number of critical decelerations (critical)

contextId

int

Road conditions

In case a road type is no included in the trip, the distance and duration percentages are equal to zero and the safety score is set to 11.

SafetyEvents

The data provided in the following table helps to display safety events on your map system and deliver the locations of harsh braking or acceleration as well as the coordinates where a tire to road adherence threshold has been crossed.

Field
Type
Description

time

double

Time since the beginning of the trip in second

latitude

double

Latitude in degree

longitude

double

Longitude in degree

velocity

double

Vehicle speed in km/h

heading

double

Vehicle heading in degree

elevation

double

Altitude in meter

distance

double

Distance travelled since the beginning of the trip in meter

type

int

Type of event 1. Adherence 2. Acceleration 3. Braking

level

int

Intensity related to the event 1. Strong 2. Harsh

value

int

Absolute value of the event:

  • in m/s2 for acceleration and braking events

  • normalized between 0 and 1 for the adherence events

The service provides the time, coordinate and severity level of each event. Two levels of severity are calculated using specific threshold values for each event.

Type of event
Unit
Strong
Harsh

Acceleration

m/s2

2.0

2.5

Braking

m/s2

-1.8

-2.4

Adherence limit

-

0.2

0.3

Pollutants

Field
Type
Description

co

double

Carbon monoxide (CO) emissions expressed in mg/km

hc

double

Hydrocarbons (HC) emissions expressed in mg/km

nox

double

Nitrogen oxide emissions (NOx) expressed in mg/km

soot

double

Soot emissions expressed in mg/km

Tire and brake wear estimates

Description

The wear analysis service has been designed to monitor the brake pads and tires wear levels. This service was designed to improve vehicle maintenance solutions and can be used to create maintenance alerts.

The wear estimation relates to the power dissipated in the tire - road or brake disc - brake contact. To compute this variable our service relies on the vehicle’s dynamic modelling that estimates the braking efforts and the efforts at the contact between the tire and the road.

For each trip, the service gives for each components (front/rear brakes/tires):

  • The worn mass fraction during the trip.

  • The total worn percentage since the installation of new tires or brakes.

Tire and brake wear indicators for a single trip

The wear analysis service measures tire wear and brake pad wear. The service allows to distinguish the front and rear axles of the vehicle. The wear is assumed to be the same for the right tire and the left tire of the vehicle. A similar assumption is made for the brake pads.

The output value corresponds to a mass fraction of the worn component (tire or brake pad). This value is expressed in thousandth part of parts-per-million (ppm) which is a unit equivalent to a parts-per-billion (ppb).

The worn mass fraction (tire or brake pad) is given for each individual trip. To obtain the total worn mass fraction, the sum of all the trip’s values must be done. The total worn mass fraction value is bounded between a minimum and a maximum value:

  • Minimum value = 0 ppb. If the total worn mass fraction is 0, the component (tire or brake pad) is assumed to have no wear.

  • Maximum value = 10910^9109ppb. If the total worn mass fraction reaches the maximum value, this means that the component (tire or brake pad) is fully worn and must be replaced.

For a tire, the maximum value for the mass fraction (10910^9109ppb) indicates that the tire has lost all its usable mass of rubber. This corresponds to a minimum tire tread height of 1.6 mm. In France, a tire must legally have a minimum tread height of 1.6 mm over its entire circumference.

The wear calculation service estimates for each trip:

  • The worn fraction of front tires

  • The worn fraction of the rear tire

  • The worn fraction of the front brakes

  • The worn fraction of the rear brakes.

Example of tire autonomy calculation:

Assuming a vehicle that has performed NNN trips, the tire autonomy ( dad_ada​ ) in km can be computed as follow:

da=f(w)×∑k=1Ndid_a=f(w)\times\sum_{k=1}^Nd_ida​=f(w)×∑k=1N​di​ with f(w)=1109×∑k=1Nwi−1f(w)=\frac{1}{10^9\times\sum_{k=1}^Nw_i}-1f(w)=109×∑k=1N​wi​1​−1

where ω is the tire worn mass fraction for the trip i (in ppb) and di is the distance (in km) of the trip i. The wear function f(ω) is a decreasing function that goes from infinity to zero. When f(ω) equals zero, the tire has no longer autonomy and must be replaced. This function is displayed below:

Total tire and brake wear indicators

In order to facilitate the integration within a vehicle maintenance service, the DriveQuant API provides for all your requests the following set of data related to any component (tires or brakes):

  • The total distance traveled with a given component (Distance)

  • The level of wear of the considered component (TotalWear)

  • The remaining autonomy before a complete wear (Autonomy)

  • The average wear speed of the considered component (WearRate)

  • The total autonomy of the considered component is assumed to be equal to the total travelled distance plus the remaining autonomy (Distance + Autonomy).

The diagram below illustrates the principle and the meaning of these quantities. The figure shows the evolution of the wear as a function of the distance traveled with the component. This is a generic representation that applies to a brake pad or a tire.

The autonomy of a set of tires or brakes is calculated for each axle (front and rear). For example, the most worn tire between the left tire and the right tire on the same axle is used.

Field
Type
Description

frontTireWear

int

Worn mass fraction of the front tires (right/ left) for current trip

Unit : thousandths part of ppm = ppb

rearTireWear

int

Worn mass fraction of the rear tires (right/left) for current trip

Unit : thousandths part of ppm = ppb

frontBrakePadWear

int

Worn mass fraction of the front brakes (right/left) for current trip

Unit : thousandths part of ppm = ppb

rearBrakePadWear

int

Worn mass fraction of the rear brakes (right/left) for current trip

Unit : thousandths part of ppm = ppb

frontTireDistance

int

Total distance analyzed for the front tires (in km)

Min. value = 0 / Max. value = 1 000 000

rearTireDistance

int

Total distance analyzed for the rear tires (in km)

Min. value = 0 / Max. value = 1 000 000

frontBrakeDistance

int

Total distance analyzed for the front brakes (in km)

Min. value = 0 / Max. value = 1 000 000

rearBrakeDistance

int

Total distance analyzed for the rear brakes (in km)

Min. value = 0 / Max. value = 1 000 000

frontTireAutonomy

int

Front tires remaining distance before change (in km)

Min. value = 0 / Max. value = 1 000 000

rearTireAutonomy

int

Rear tires remaining distance before change (in km)

Min. value = 0 / Max. value = 1 000 000

frontBrakeAutonomy

int

Front brakes remaining distance before change (in km)

Min. value = 0 / Max. value = 1 000 000

rearBrakeAutonomy

int

Rear brakes remaining distance before change (in km)

Min. value = 0 / Max. value = 1 000 000

frontTireTotalWear

double

Total worn mass percentage of the front tires (right/left)

Min. value = 0% / Max. value = 100%

rearTireTotalWear

double

Total worn mass percentage of the rear tires (right/left)

Min. value = 0% / Max. value = 100%

frontBrakeTotalWear

double

Total worn mass percentage of the front brakes (right/left)

Min. value = 0% / Max. value = 100%

rearBrakeTotalWear

double

Total worn mass percentage of the rear brakes (right/left)

Min. value = 0% / Max. value = 100%

frontTireWearRate

double

Average wear rate for the front tires (in %/1000 km )

rearTireWearRate

double

Average wear rate for the rear tires (in %/1000 km )

frontBrakeWearRate

double

Average wear rate for the rear brakes (in %/1000 km )

rearBrakeWearRate

double

Average wear rate for the rear brakes (in %/1000 km )

The wear rate measures the component wear (in %) as a function of distance. This variable allows to compare vehicles and to inform a vehicle fleet manager whose components are wearing out too quickly. The wear rate is related to the type of vehicle, the driving style, the type of road used and the driving condition. This is why its value can change if the typology of trips changes and if the vehicle is driven by several drivers who have different driving styles.

Driver distraction (score)

Distracted driving becomes a serious problem and is becoming a major road safety issue.

That's why we've developed a service that measures the driver's interactions with his smartphone while driving. The objective is to increase driver awareness through a distraction score. This can be used to compare drivers, to classify them or to organize driving challenges.

The DriveKit SDK is capable of measuring the two main indicators of distracted driving:

  1. screen unlocks,

  2. and outgoing or incoming (and answered) phone calls.

The distraction score depends on 2 parameters :

  • the smartphone unlocking frequency;

  • the total duration of the call (or calls if there are several in the same trip).

Each parameter is giving a sub-score from 0 to 10. The distraction score is the minimum between these two sub-scores.

The sensitivity function linking the number of unlocks per 100 km to the unlock score is shown below.

The sensitivity function linking the call duration to the call score is shown below.

This service is only available with the DriveKit mobile SDK.

The response body includes the trip scores as well as detailed data related to unlocks and calls. This way you can better understand the score construction and provide clear explanations to the driver.

The data returned by the service are listed in the table below:

Field
Type
Description

nbUnlock

int

Number of phone screen unlock events

nbLock

int

Number of phone screen lock events

distance

double

Relative distance traveled with the screen on (in %)

distanceM

double

Distance traveled with the screen on (in m)

duration

double

Relative duration traveled with the screen on (in %)

durationS

double

Duration traveled with the screen on (in s)

score

double

Phone distraction score (Min. value = 0, Max. value = 10)

scoreUnlock

double

Distraction sub-score which takes into account the number of locking/unlocking

scoreCall

double

Distraction sub-score which takes into account the number of calls during the trip

calls

array[object]

Call

The Driver distraction score provides an array with all the calls answered or made by the driver. For each call, it contains information about its conditions.

Value
Type
Description

id

int

Unique identifier of the call

start

double

Seconds from beginning of the trip when call starts

end

double

Seconds from beginning of the trip when call ends

durationS

double

Duration traveled in call (in s)

duration

double

Relative duration traveled in call (in %)

distanceM

double

Distance traveled in call (in m)

distance

double

Relative distance traveled in call (in %)

status

string

INCOMING : incoming call

OUTGOING : outgoing call

UNKNOWN : unknown call status

audioSystem

string

Audio system used to make the call (SPEAKER, LOUDSPEAKER, A2DP, HANDSFREE, HEADPHONE, CAR_AUDIO, UNKNOWN)

forbidden

boolean

true if the call is forbidden

false if the call is authorized (made with handsfree)

Response body example

"driverDistraction": {
    "nbUnlock": 0,
    "durationUnlock": 13,
    "durationPercentUnlock": 2.5,
    "distanceUnlock": 33.54196351499925,
    "distancePercentUnlock": 0.4636710466546759,
    "score": 10,
    "scoreUnlock": 10,
    "scoreCall": 10,
    "calls": [
      {
        "id": 0,
        "start": 85,
        "end": 118,
        "durationS": 33,
        "duration": 6,
        "distanceM": 734,
        "distance": 10,
        "status": "INCOMING",
        "audioSystem": "HANDSFREE",
        "forbidden": false
      },
      {
        "id": 1,
        "start": 320,
        "end": 344,
        "durationS": 24,
        "duration": 5,
        "distanceM": 295,
        "distance": 4,
        "status": "UNKNOWN",
        "audioSystem": "HANDSFREE",
        "forbidden": false
      }
    ]
  }

Example of use

The screenshot below shows how to display the phone use data on a mobile phone interface:

Driver distraction (events)

The distraction score service provides additional information related to screen unlock and screen lock events. Thus, it is possible to get the location of events related to phone use. These informations are useful if you need to display these data on your mapping system or if you want to perform advanced data analysis.

The table below lists all the data returned by the service:

Field
Type
Description

time

double

Time since the beginning of the trip (in s)

latitude

double

Latitude (in deg)

longitude

double

Longitude (in deg)

velocity

double

Vehicle speed (in km/h)

heading

double

Vehicle heading (in deg)

elevation

double

Altitude (in m)

distance

double

Distance travelled since the beginning of the trip (in m)

type

int

Type of event : (1) Screen ON and (2) Screen OFF

Response body example

"distractionEvents": [
        {
            "time": 248.0,
            "latitude": 48.92460229,
            "longitude": 2.38685389,
            "velocity": 0.0,
            "heading": 0.6352998743575466,
            "elevation": 79.0,
            "distance": 3157.72999073565,
            "type": 1
        },
        {
            "time": 273.0,
            "latitude": 48.92434025,
            "longitude": 2.3891527,
            "velocity": 46.5839984893799,
            "heading": 0.006233303539059223,
            "elevation": 78.85714285714286,
            "distance": 3267.4199903160334,
            "type": 2
        }
    ]

CallEvents

Thanks to the distracted driving analysis service, you will be able to obtain contextualized and geolocalized data related to the detected events. This information is of great importance for the evaluation of the road risk and to help the driver to improve (by presenting this information on a map for example).

Value
Type
Description

time

double

Time in second since the beginning of the trip

latitude

double

Latitude in degree

longitude

double

Longitude in degree

velocity

double

Vehicle speed in km/h

heading

double

Vehicle heading in degree

elevation

double

Altitude in meter

distance

double

Distance travelled during the call in meter

type

int

3: Call start

4: Call end

duration

int

Call duration in seconds

index

int

Position of the beginning of the event in the route date (phone call beginning of phone unlocking)

audioSystem

string

Audio system used to make the call (SPEAKER, LOUDSPEAKER, A2DP, HANDSFREE, HEADPHONE, CAR_AUDIO, UNKNOWN)

callType

string

Call type

Allowed values: INCOMING, OUTGOING, UNKNOWN

forbidden

boolean

true if the call is forbidden

false if the call is authorized (made with handsfree)

Response body example

"callEvents": [
   {
     "time": 85,
     "latitude": 46.90593,
     "longitude": -0.23254,
     "velocity": 77.03999862670898,
     "heading": -4.978726223953685,
     "elevation": 142.34007335844495,
     "distance": 0,
     "type": 3,
     "duration": 1,
     "index": 85,
     "audioSystem": "HANDSFREE",
     "callType": "INCOMING",
     "forbidden": false
   }, {
     "time": 118,
     "latitude": 46.91235,
     "longitude": -0.23023,
     "velocity": 85.60800247192383,
     "heading": -4.889215763272453,
     "elevation": 145.41845121837798,
     "distance": 734,
     "type": 4,
     "duration": 33,
     "index": 118,
     "audioSystem": "HANDSFREE",
     "callType": "INCOMING",
     "forbidden": false
   }, {
     "time": 320,
     "latitude": 46.90536,
     "longitude": -0.22448,
     "velocity": 45.93600082397461,
     "heading": -9.696301173649006,
     "elevation": 147.3037109375,
     "distance": 0,
     "type": 3,
     "duration": 1,
     "index": 320,
     "audioSystem": "HANDSFREE",
     "callType": "UNKNOWN",
     "forbidden": false
   },{
     "time": 344,
     "latitude": 46.90387,
     "longitude": -0.22633,
     "velocity": 34.23600082397461,
     "heading": -7.896966651865014,
     "elevation": 142.9379156203497,
     "distance": 295,
     "type": 4,
     "duration": 24,
     "index": 344,
     "audioSystem": "HANDSFREE",
     "callType": "UNKNOWN",
     "forbidden": false
   }
 ]

Speed Limit

This service measures distance and driving time when the vehicle speed exceeds the speed limit.

From this information, a speed limit score is calculated. The speed limit score is 10 if the overspeed distance is zero. The speed limit score decreases with the increase in the percentage of distance spent in overspeeding.

The sensitivity function linking the relative speeding distance (in %) with the speeding score is shown below.

This service returns a global (or trip) score for the entire trip as well as several sub-scores corresponding to each of the legal speed portions traveled during the trip.

The global (or trip) score is the average of the sub-scores weighted by distance.

Field
Type
Description

distance

int

trip distance (m)

duration

int

trip duration (s)

speedingDistance

int

Distance travelled at a speed above the limit (m)

speedingDuration

int

Duration spent at a speed above the limit (s)

score

double

Speeding score

speedLimitContexts

array[object]

SpeedLimitContexts

Field
Type
Description

speedLimit

int

Speed limit (in km/h) for the portion of the trip

distance

int

Total distance (in m) for the portion of the trip limited at the speed limit value

duration

int

Total duration (in s) for the portion of the trip limited at the speed limit value

speedingDistance

int

Distance travelled at a speed above the limit (in m) within the speed limit portion

speedingDuration

int

Duration spent at a speed above the limit (in s) within the speed limit portion

score

double

Speeding score for a given speed limit portion

Response body example

{
"speedingStatistics" : {
            "distance" : 6835,
            "duration" : 613,
            "speedingDistance" : 280,
            "speedingDuration" : 14,
            "score" : 9.55,
            "speedLimitContexts" : [ 
                {
                    "speedLimit" : 30,
                    "distance" : 21,
                    "duration" : 6,
                    "speedingDistance" : 0,
                    "speedingDuration" : 0,
                    "score" : 10.0
                }, 
                {
                    "speedLimit" : 50,
                    "distance" : 2378,
                    "duration" : 352,
                    "speedingDistance" : 169,
                    "speedingDuration" : 9,
                    "score" : 8.83
                }, 
                {
                    "speedLimit" : 70,
                    "distance" : 2153,
                    "duration" : 122,
                    "speedingDistance" : 111,
                    "speedingDuration" : 5,
                    "score" : 9.38
                }, 
                {
                    "speedLimit" : 90,
                    "distance" : 2283,
                    "duration" : 133,
                    "speedingDistance" : 0,
                    "speedingDuration" : 0,
                    "score" : 10.0
                }
            ]
        }
    }
}

SpeedingEvents

The service that computes the speeding score also returns location-based information about overspeeding events.

This type of information is used to indicate on a map the places on the trip where the speed of the vehicle exceeds the speed limit.

The start and end positions of overspeeding segments are included in the SpeedingEvents table.

Value
Type
Description

time

double

Time in second since the beginning of the trip

latitude

double

Latitude in degree

longitude

double

Longitude in degree

type

int

1 = Overspeeding segment start point

0 = Overspeeding segment endpoint

index

int

Index of the speeding event in the matched route vector.

Response body example

"speedingEvents": [
    {
      "longitude": 2.240690719770278,
      "latitude": 48.87119316290749,
      "time": 96,
      "type": 1,
      "index": 36
    },
    {
      "longitude": 2.2389993413999454,
      "latitude": 48.87022711541927,
      "time": 106,
      "type": 0,
      "index": 39
    }
]

Introduction

To automatically record a trip when the application runs in background, the DriveKit SDK must be allowed to access the phone's sensors.

Access to this data is allowed by iOS and Android under certain conditions. It is essential to inform the user and ask him to grant the required permissions to allow the application to access the data measured by the smartphone's sensors.

To help you collect consent from your users, the DriveKit SDK provides a graphical component, Permissions Utils, which displays the appropriate requests after the installation of the application.

The Permissions Utils component also contains a diagnosis functionality that alerts the user if the smartphone settings are not properly set up and guides the user to solve the detected issue.

Get started

Integration

The Common UI SDK is a core configuration module for all DriveKit UI modules.

To add Common UI module to your app, add the following pod to your podfile:

target 'my-target' do
  pod 'DriveKitCommonUI'
end

Then, run pod install

Initialization

import DriveKitCoreModule
import DriveKitCommonUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     DriveKit.shared.initialize()
     DriveKitUI.shared.initialize()
     ...
}

This method will initialize the SDK with the default configuration set up by DriveQuant.

It is possible (from Swift, not Objective-C) to provide some parameters to this DriveKitUI initialization method in order to set custom values for colors (colors: DKColors), fonts (fonts: DKFonts), and/or text localization (overridedStringsFileName: String?).

Configurations

Colors

The colors that can be configured are listed in the table below:

Name

Description

Default value

primaryColor

Main app color

#0B4D6E

secondaryColor

Call to action color

#77E2B0

mainFontColor

Main font color

#161616

complementaryFontColor

Secondary font color

#9E9E9E

fontColorOnPrimaryColor

Color of a text displayed on an element whose color is primaryColor

#FFFFFF

fontColorOnSecondaryColor

Color of a text displayed on an element whose color is secondaryColor

#FFFFFF

backgroundViewColor

Background color

#FAFAFA

neutralColor

Color of the separating lines

#F0F0F0

warningColor

Warning color (non-critical hint)

#F7A334

criticalColor

Alert color (critical hint)

#E52027

navBarElementColor

Color of elements (title and items) in the navigation bar

fontColorOnPrimaryColor

To override the default colors configuration, you should create a subclass of DKDefaultColors and override the colors that you want to change (or you can create an object implementing the DKColors protocol, necessary if your project is in Objective-C for instance). Then pass an instance of this object as a parameter of the configureColors method.

import DriveKitCoreModule
import DriveKitCommonUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     DriveKit.shared.initialize()
     DriveKitUI.shared.initialize()
     DriveKitUI.shared.configureColors(Colors())
     ...
}

class Colors: DKDefaultColors {
    override func primaryColor() -> UIColor {
        return UIColor.red
    }
}

Fonts

The Common UI configuration module allows to set up two fonts:

  1. primaryFont: this is the main font used in the application. The default value is Roboto.

  2. secondaryFont: this is the font used on the page titles or to emphasize a specific point. The default value is Roboto.

To override the fonts, you can add the primary and secondary fonts to the CommonUI SDK by calling the configureFonts method as in this following example:

import DriveKitCoreModule
import DriveKitCommonUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     DriveKit.shared.initialize()
     DriveKitUI.shared.initialize()
     DriveKitUI.shared.configureFonts(Fonts())
     ...
}

class Fonts: DKDefaultFonts {
    override func primaryFont() -> String {
        return "Impact"
    }
}

Note: From Objective-C, it is not possible to subclass the DKDefaultFonts class. To override the fonts, it is thus necessary to create a class implementing the DKFonts protocol.

Text Localization

Contents of each DriveKit UI module are translated into 7 languages: English, French, German, Spanish, Italian, Danish and Portuguese.

DriveKit simplifies the internationalization of your application and it is possible to add other languages.

DriveKit Common UI contains a number of basic text keys used in other DriveKit UI modules. You can override these keys to customize your application.

To help make the text keys in the code easier to read, a specific nomenclature has been set up: dk_<module name>_<key description>.

For the Common UI module, all localizable keys are prefixed with: dk_common.

There are several files containing text keys:

  • A .strings file in the common UI module containing generic keys to all modules.

  • One file per UI module containing module-specific text keys.

Text customization

import DriveKitCoreModule
import DriveKitCommonUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    DriveKit.shared.initialize()
    DriveKitUI.shared.initialize()
    DriveKitUI.shared.configureStringsFileName("OverridedStrings")
    ...
}

Add language

Get analytics

For analytics purposes, you can tag screens of any DriveKit UI component by providing to this following method an instance of an object conforming to DKAnalytics protocol:

DriveKitUI.shared.configureAnalytics(Analytics())

Where the Analytics object is for instance:

class Analytics: DKAnalytics {
    func trackScreen(_ screen: String, viewController: UIViewController) {
        // TODO: manage screen tracking here with the tool of your choice.
    }

    func trackEvent(_ event: DKAnalyticsEvent, parameters: [String : Any]?) {
        // TODO: manage event tracking here with the tool of your choice.
    }
}
DriveKitUI.shared.configureAnalytics(Analytics(), tagsFileName: "CustomAnalyticsTags")

If, in the plist, a value is empty, the tracking is disabled for this screen.

The trackEvent method allows you to add additional information that may be useful for analysis. For example, that method is called each time the user opens the trip detail screen.

Get started

Prerequisite

Integration

To add the Permissions Utils UI module to your app, add the following line to your dependencies in your application build.gradle file:

dependencies {
    implementation 'com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version'
}

Replace $drivekitui_version with the DriveKit version you are using in your app

Initialization

Then, to initialize the module in your app, you must call the initialization method in onCreate method of your Application class:

fun initialize()

Main configurations

Permission management

On Android, the user must grant the SDK access to:

  • the phone's location and background activity monitoring to enable the trip detection function included in the Trip Analysis component;

  • the Nearby Devices permission to detect Bluetooth devices;

  • the background execution authorization to avoid the application being stopped by the power saving system.

Starting from Android 13, the user also needs to authorize the app to send notifications.

The Permissions Utils component provides a set of screens to guide the user through the selection of the right options.

Once all permissions have been granted by the user, you are warned by the closure passed in parameter:

The Permissions Utils component automatically manages the permission request workflow depending on the version of Android installed on the user's smartphone.

SDK diagnosis

Diagnosis state

Each monitored setting has three levels of criticity defined by the enum PermissionStatus : VALID, NOT_VALID and WARNING.

  • VALID: The setting is correctly configured (device sensor is ON and/or permission is authorized). There is no error and the trip analysis will work well.

  • NOT_VALID: The setting is not correctly configured (device sensor is OFF and/or permission is declined). There is an error and the trip analysis will not work as expected.

  • WARNING: The setting is not correctly configured, but it will not affect the trip analysis.

Diagnosis screen areas

The diagnosis screen is divided into three areas:

  1. The first displays the status of sensors and permissions.

  2. The second contains a quick link to the battery optimization functions.

  3. The third displays a contact button to reach support.

The first two areas are always displayed. The third is optional.

The diagnostic function of the SDK has the following configurations:

  • In area 1, the sensors and permissions to be checked are selected automatically except for the Bluetooth sensor. If your application does not use a Bluetooth device or an iBeacon, it is not necessary to monitor the status of the Bluetooth sensor.

  • In area 3, it is possible to configure the recipient's email address for the support request or a web address to which the user can be directed.

To use the app diagnosis display into your app, you must enter the following lines of code:

Bluetooth sensor status check

For natural triggering (i.e. from the phone's sensors), Bluetooth access is not required.

Access to the Bluetooth sensor is required in the two cases described below:

  1. To enable automatic start of trip recording from an iBeacon device.

  2. To enable automatic start of trip recording from a Bluetooth device.

If the Bluetooth sensor is turned off on the device, iBeacon and Bluetooth devices won't be detected.

Moreover, phone calls during a trip might not be detected and the distraction score can be affected.

Support Request Management

The user can make a support request if the application does not work properly.

When the user clicks on the support request button, you can choose between two actions:

  1. An email will be automatically composed,

  2. or a redirection to a web page of your choice will be made.

The email contains the key information to ease the diagnosis of a problem (status of permissions and phone sensors). The recipient's email is configurable, as well as other parameters:

If you want to redirect the user to a web page instead of composing an email, you have to add the following line:

In this specific case, there is no way to obtain information about authorization and sensor status.

If you do not configure the contact type, this area will be hidden and will not appear on the diagnosis screen.

Introduction

The Driver Data component manages the download and display in your mobile application of all trips made by the user.

The Driver Data component continuously performs synchronization between the remote DriveQuant database and the local database of the mobile SDK.

The Driver Data component has been designed to simplify the integration of DriveQuant services into your application and to drastically reduce your development time.

It has several benefits:

  • The SDK contains its own database. You do not need to create a local database (or modify the existing one) to persist the user driving data.

  • Network calls are fully automated. You do not need to implement API requests for driver data recuperation.

  • The SDK includes a graphics library that displays the user's trip data. You do not need to develop new screens in your application. The trip analysis display screens are configurable and can be easily adapted to the style of your mobile application.

Get started

Integration

The Common UI module is a core configuration module for all DriveKit UI modules.

To add Common UI module to your app, add the following line to your dependencies in your application build.gradle file:

Replace $drivekitui_version with the DriveKit version you are using in your app

Initialization

This method will initialize the SDK with the default configuration set up by DriveQuant.

Configurations

Colors

The colors that can be configured are listed in the table below:

To override the default colors configuration, you just have to add the colors you want to change in the file res/values/colors.xml in your app:

The flavor "colorsTest" of the demo application is an example of colors customization.

Fonts

The Common UI configuration module allows to set up two fonts:

  1. primaryFont: this is the main font used in the application. The default value is Roboto.

  2. secondaryFont: this font is used on the page titles or to emphasize a specific point. The default value is Roboto.

To override the primary font, define your font family in the file res/font/dkprimary.xml in your app:

To override the secondary font, define your font family in the file res/font/dksecondary.xml in your app:

The flavor "fontsTest" of the demo application customizes the fonts to test and see where the different fonts are used.

Text Localization

Contents of each DriveKit UI module are translated into 7 languages: English, French, German, Spanish, Italian, Danish and Portuguese.

DriveKit simplifies the internationalization of your application and it is possible to add other languages.

DriveKit Common UI contains a number of basic text keys used in other DriveKit UI modules. You can override these keys to customize your application.

To help make the text keys in the code easier to read, a specific nomenclature has been set up: dk_<module name>_<key description>.

For the Common UI module, all localizable keys are prefixed with: dk_common.

There are several files containing text keys:

  • A string.xml file in the common UI module containing generic keys to all modules.

  • One file per UI module containing module-specific text keys.

Text customization

Add language

Get analytics

You can retrieve some data and build analytics for any DriveKit UI component. To enable the feature, call the following method:

trackScreen() method is called when a screen is displayed (i.e. trips list, trip detail, etc.).

In order to customize screens values, you have to override keys you can find in dk_analytics.xml in each DriveKit UI component.

trackEvent() allows adding additional information that may be useful for analysis. For example, that method is triggered each time the user is opening the trip detail screen.

Get started

Prerequisite

If you use Driver Data without having initialized DriveKit, the SDK may not work properly in your application.

Integration

Get framework

The Driver Data SDK is available on Cocoapods master repo.

To access framework in the repository, add the following lines to your Podfile:

Then, run pod install.

Initialization

Then, to initialize Driver Data module in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate file.

Get driver trips

SynchronizationType can have 2 values:

  • defaultSync: if this value is used, the SDK will try to synchronize local trips with DriveQuant backend to get new trips or modified trips, and then return the trip list via the completionHandler.

  • cache: if this value is used, no synchronization will be performed and only trips previously synchronized will be returned via the completionHandler.

TripSyncStatus in the completionHandler can have 4 values:

  • noError: Synchronization has been successfully performed.

  • cacheDataOnly: SynchronizationType has been set to cache.

  • failedToSyncTripsCacheOnly: Synchronization has failed, only trips previously synchronized are returned.

  • syncAlreadyInProgress: A synchronization is in progress, only trips previously synchronized are returned until the synchronization is finished.

Trips are returned and sorted by end date in descending order.

If train trips have been recorded by Trip Analysis SDK, they won't be returned by this method.

Example:

Get specific trip

The itinId parameter is the unique identifier for a trip.

When you call this method, you will get trip data and trip safety events. If safety events are not synchronized locally for the trip, a synchronization with DriveQuant backend will be performed and then, the trip will be returned with safety events synchronized.

Example:

Get trip road data

To get road data of the trip (latitude, longitude), you have to call the following method:

If route value in completionHandler is nil , the synchronization has failed.

Example:

Delete a trip

To delete a trip, you have to call the following method:

The itinId parameter is the unique identifier for a trip.

Example:

Get driver synthesis

To get driver synthesis data, you have to call the following method:

SynchronizationType can have 2 values:

  • defaultSync: if this value is used, the SDK will try to synchronize the driver synthesis data with DriveQuant backend and then return it via the completionHandler.

  • cache: if this value is used, no synchronization will be performed and the data retrieved during the last synchronisation will be returned via the completionHandler.

SynthesisSyncStatus in the completionHandler can take 3 values:

  • cacheDataOnly: SynchronizationType has been set to cache.

  • noError: Synchronization has been successfully performed.

  • failedToSyncSynthesisCacheOnly: Synchronization has failed, only data retrieved during the last synchronisation is returned.

Example:

periods attribute contains periods you are interested in: .week , .month and/or .year.

  • defaultSync: if this value is used, the SDK will try to synchronize timelines with DriveQuant backend and then return them via the completionHandler.

  • cache: if this value is used, no synchronization will be performed and the data retrieved during the last synchronisation will be returned via the completionHandler.

  • cacheDataOnly: SynchronizationType has been set to cache.

  • noError: Synchronization has been successfully performed.

  • failedToSyncTimelineCacheOnly: Synchronization has failed, only data retrieved during the last synchronisation are returned.

  • noTimelineYet: Synchronization has been successfully performed and there is currently no timeline.

Get driver timelines

To get driver timelines, you have to call the following method:

TimelineSyncStatus in the completionHandler can take 4 values:

  • cacheDataOnly: SynchronizationType has been set to cache.

  • noError: Synchronisation has been successfully performed.

  • failedToSyncTimelineCacheOnly: Synchronisation has failed, only data retrieved during the last synchronisation are returned.

  • noTimelineYet: Synchronisation has been successfully performed and there is currently no timeline.

Example:

Get driver profile

To get driver profile, you have to call the following method:

SynchronizationType can have 2 values:

  • defaultSync: if this value is used, the SDK will try to synchronize the driver profile with DriveQuant backend and then return it via the completionHandler.

  • cache: if this value is used, no synchronisation will be performed and the data retrieved during the last synchronisation will be returned via the completionHandler.

DKDriverProfileStatus in the completionHandler can take 4 values:

  • success: Synchronization type has been successfully performed.

  • failedToSyncDriverProfileCacheOnly: Synchronisation has failed, only data retrieved during the last synchronisation is returned.

  • noDriverProfileYet: Synchronisation has been successfully performed and there is currently no driver profile for this user.

  • forbiddenAccess: Your team doesn’t have access to this data.

References

Analytics tags

Custom metadata

If your use case requires it, it is possible to add your own data in the trip analysis request. For example, it can be data that is specific to your trip, application or user identification system.

Set metadata

You can add additional metadata to your trip by calling the following method:

The metadata must be represented as a key/value object where the key and value have a String type.

The metadata can be set any time before the end of a trip.

If metadata is sent, it will also be added to the push data request in the metaData field.

Get metadata

It is possible to get a copy of configured metadata thanks to the following method on DriveKitTripAnalysis:

Note: Any modification on the returned object has no effect on the metadata sent with a trip.

Update metadata

To update a value in metadata, call the following method:

Delete a specific metadata

To delete a specific value in metadata, call the following method:

Delete all metadata

To delete all values in metadata, call this method:

Bluetooth usage

Principle

Bluetooth wireless technology is a common solution in modern vehicles. Most drivers know that by pairing their Bluetooth smartphone with their car stereo receiver, they will be able to make hands-free calls or to stream their music to the car audio system.

Once the smartphone's paired with the vehicle, it automatically connects to it if the vehicle is started.

Trip Analysis component is capable of detecting this event to start a trip analysis.

A Bluetooth device is identified by a unique MAC address and an optional name. It can be detected by the SDK and used to trigger the trip analysis.

The use of the vehicle Bluetooth detection is a simple and cost-effective solution to identify the trips made with your vehicle.

Configure a Bluetooth device

You can retrieve all Bluetooth devices paired to the smartphone by calling the following method:

You can add Bluetooth devices to Trip Analysis component by calling the following method:

If you want to remove Bluetooth devices from SDK configuration, just call the method with an empty list.

Bluetooth device required

Pairing the vehicle's Bluetooth system improves the trip detection and analysis. With this feature you can decide to enable or disable the trip recording when the Bluetooth device is not connected. There are two possibilities:

  1. the trip can be recorded even if the smartphone is not connected to the Bluetooth device.

  2. the trip recording will be cancelled if the smartphone is not connected to the Bluetooth device.

This choice depends on your use case. In general, if you only want to record trips made with the vehicle equipped with the paired Bluetooth system, you must prefer the second choice.

To avoid trip recording when the Bluetooth device is not connected, call the following method with parameter to true:

To enable trip recording regardless of the state of the Bluetooth system (connected or not connected to the smartphone), call the following method with parameter to false:

TripListener

The TripListener interface provides useful information and events about trips analyzed by DriveKit.

For example, you can be informed when a trip analysis has started, finished, canceled, when a crash is detected, etc.

Add a TripListener

You can remove a specific listener using the following method:

To remove all TripListeners objects:

If you remove all your trip listeners or forget to add one, your app will not receive any feedback from the trip analysis module. It will not prevent the analysis from working but your code will not be able to execute its own logic (UI updates, notification, etc.).

Do not forget to remove your TripListener objects when you don't need it anymore to prevent memory leaks.

TripListener interface includes several methods to implement:

End of trip notification: Depending on the trip analysis service's response in the tripFinished() callback, we recommend that you specify the notification content if you decide to display a user feedback:

  • For a vehicle trip, you can display a message such as: Your trip has been analyzed.

  • For a trip by rail it is better to display the following message: Your trip was made by train.

Get the trip response status (Deprecated)

This method has been deprecated and will be removed at the end of 2025.

Once the DriveQuant servers has analyzed a trip, the tripFinished() callback is triggered with the data in the PostGenericResponse object.

It can be useful to check the trip response status in order to check for example if the trip is valid or not with detailed information.

To do this, call the following method:

disabled the SDK auto-initialization

Before starting DriveKit Permissions Utils UI integration, make sure that you have initialized module, especially if you have .

On a Github repository, you can find a demo app (for and ) and the source code of Permissions Utils UI that you can use as an example.

If you have , the Permissions Utils UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitPermissionsUtilsUI:

The user must enable the developer mode in Android. The explains well how to proceed.

Android offers a clear and exhaustive listing the new features and changes related to Android 15.

DriveQuant recommends to specifically pay attention about the which is now enabled by default when your app is targeting Android 15.

If your app is not ready to support edge-to-edge, you can disable it by using the attribute.

The last part is to ensure that the app is working as expected. The best way to do this is to compare your app's behaviour with the and/or the ; which already support Android 15.

If you experience any problems with DriveKit, please contact .

DriveQuant services provide additional data by collecting all vehicle trips so you can easily retrieve statistics for each of your vehicles. We recommend to before requesting the trip analysis API if you target a vehicule mantenance use case.

The request includes a driverId and a vehicleId: This is common when a group of drivers can use several vehicle within a fleet. The total number of assets may be the number of unique vehicleId's or driverId's. Billing and counting will depend on your business model and the difference between the number of drivers and vehicles. Please sales department to find out the best pricing model.

The sample period for all input vectors must be 1 second. The sampling frequency of 1Hz is a standard for GPS sensors. in case your telematics device does not satisfy this constraint, please to determine what alternative can be applied.

Vehicle power in hp. This value must be entered in horsepower. In case you only have the engine power in kW you can apply the following formula:

see

see

see

see

see

see

Possible values are described .

See :

Energy class definition

Array of

Total Mass of in kg

Average Mass of per unit of distance in g/km

Idle emission in g/km

Idle mass in kg

Array of

Total Mass of in kg

Average emissions in g/km

Array of

Min. value = 0 / Max. value =

Min. value = 0 / Max. value =

Min. value = 0 / Max. value =

Min. value = 0 / Max. value =

Array of

We recommend you to test this component in the before you integrate it in your application.

On this, you have a demo app and source code that you can use as an example.

If you have , an initialization phase is required to ensure that Common UI module works perfectly. To initialize Common UI module in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate file.

To override a text key in the common UI module, simply define the keys to be modified in a .strings file at the application level and configure the filename in the common UI module. The text keys can be directly retrieved on , in the Localizable folder of each module.

The translation file can be retrieved from . Add it to your application after adding the appropriate translation(s).

The screen String received in the trackScreen method is the value associated to one of the keys, corresponding to the visited screen. If you want to customize screen tags, you can provide the path to a plist file (see the ) with your custom values in the configuration method:

Before starting DriveKit Permissions Utils UI integration, make sure that you have initialized module, especially if you have .

On a, you can find a demo app and the source code of Permissions Utils UI that you can use as an example.

If you have , the Permissions Utils UI module must also be manually initialized.

Area 2 is always displayed if the Android version includes power-saving features (introduced from Android 6.0 - ).

The Driver Data component uses standard and powerful libraries recommended by Apple and Google for persistence management. On Android, the is implemented. On iOS, the persistence framework provided by Apple is used.

We recommend you to test this component in the before you integrate it in your application.

On a, you have a demo app and source code that you can use as an example.

If you have , an initialization phase is required to ensure that Common UI module works perfectly. To initialize Common UI module in your app, you must call the initialization method in onCreate method of your application class.

You can override any texts to customize your application. To override a text key, simply define the keys to be modified in a string.xml file at the application level. The text keys can be directly retrieved on , in the src/main/res/values folder of each module.

The translation file can be retrieved from in the various DriveKit UI modules and integrated into the values-<Locale> folder of the app.

When the method is called, you just have to call your analytics solution like Google Analytics for Firebase. The screen String received in the trackScreen method is the value associated with one of the keys , corresponding to the visited screen.

Before starting DriveKit Driver Data integration, make sure that you have .

If you have , an initialization phase is required to use the feature included in the Driver Data module. In the application's AppDelegate file, import DriveKitDriverData:

To get , you have to call the following method:

The second argument in the completionHandler is the list of objects.

To get a specific , you have to call the following method:

TripSyncStatus can have the same value as and the value failedToSyncSafetyEvents if the safety events synchronization failed.

The second argument in the completionHandler is the requested object, if exists.

The second argument in the completionHandler is a list of object, one per period requested.

The second argument in the completionHandler is the object requested.

Metadata is persisted, so if you want to send it only for one trip, you need to remove it at the end of the trip, on the callback, by checking if state is inactive.

A detailed description of BluetoothData class is available .

If you have configured the and the bluetooth device as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.

The trip recording lifecycle is exhaustively described in part.

Method
Description

The callback method tripFinished(post: PostGeneric, response: PostGenericResponse) is replaced by tripFinished(result: TripResult) which directly provides the useful information (see ).

The model is described in the References part.

P[hp]=P[kW]/0.7355P [hp] = P [kW] / 0.7355P[hp]=P[kW]/0.7355
CO2\mathrm{CO_2}CO2​
CO2\mathrm{CO_2}CO2​
CO2\mathrm{CO_2}CO2​
CO2\mathrm{CO_2}CO2​
CO2\mathrm{CO_2}CO2​
CO2\mathrm{CO_2}CO2​
10910^9109
10910^9109
10910^9109
10910^9109
iOS
Android
official documentation
documentation
Behavior changes: all apps
Behavior changes: Apps targeting Android 15 or higher
Edge-to-edge enforcement
windowOptOutEdgeToEdgeEnforcement
For internal modules
For UI modules
DriveQuant's app
DriveKit Demo App
us
add a new vehicle
contact DriveQuant
contact us
Github repository
Github
GitHub
in this array
default tags file
Github repository
Common UI
disabled the SDK auto-initialization
disabled the SDK auto-initialization
disabled the SDK auto-initialization
here
DriveKit Demo App
Common UI
disabled the SDK auto-initialization
disabled the SDK auto-initialization
PermissionsUtilsUI.showPermissionViews(this, object : PermissionViewListener {
       override fun onFinish() {
          //Code called when all permissions in the list are properly granted
       }
   })
PermissionsUtilsUI.INSTANCE.showPermissionViews(this, new PermissionViewListener() {
   @Override
   public void onFinish() {
       //Code called when all permissions in the list are properly granted
   }
});
DriveKitNavigationController.permissionsUtilsUIEntryPoint?.let {
   it.startAppDiagnosisActivity(this)
}
PermissionsUtilsUIEntryPoint permissionsUtilsUIEntryPoint = DriveKitNavigationController.INSTANCE.getPermissionsUtilsUIEntryPoint();
if (permissionsUtilsUIEntryPoint != null) {
   permissionsUtilsUIEntryPoint.startAppDiagnosisActivity(this);
}
PermissionsUtilsUI.configureContactType(ContactType.EMAIL(object : ContentMail {
   override fun getBccRecipients(): List<String> {
       //return a list of bcc recipients
   }

   override fun getMailBody(): String {
       //return mail body
   }

   override fun getRecipients(): List<String> {
       //return list of recipients
   }

   override fun getSubject(): String {
       //return mail body message
   }   

   override fun overrideMailBodyContent() {
      //return true if you want to override the default support mail body 
   }
})
PermissionsUtilsUI.INSTANCE.configureContactType(new ContactType.EMAIL(
       new ContentMail() {
           @NotNull
           @Override
           public List<String> getRecipients() {
               //return list of recipients
           }

           @NotNull
           @Override
           public List<String> getBccRecipients() {
               //return a list of bcc recipients
           }

           @NotNull
           @Override
           public String getSubject() {
                //return subject            
           }

           @NotNull
           @Override
           public String getMailBody() {
                //return mail body message
           }

           @Override
           public boolean overrideMailBodyContent() {
               //return true if you want to override the default support mail body
           }
       }
));
PermissionsUtilsUI.configureContactType(ContactType.WEB(Uri.parse("https://www.docs.drivequant.com")))
PermissionsUtilsUI.INSTANCE.configureContactType(new ContactType.WEB(Uri.parse("https://www.docs.drivequant.com/")));
fun configureContactType(contactType: ContactType)
PermissionsUtilsUI.INSTANCE.configureContactType(ContactType.NONE.INSTANCE);
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-common-ui:$drivekitui_version'
}
class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        (…)
        DriveKitUI.initialize()
    }
}
public class MyApplication extends Application {
   @Override
   public void onCreate() {
       super.onCreate();
       (…)
       DriveKitUI.initialize();
}}

Name

Description

Default value

primaryColor

Main app color

#0B4D6E

secondaryColor

Call to action color

#77E2B0

mainFontColor

Main font color

#161616

complementaryFontColor

Secondary font color

#9E9E9E

fontColorOnPrimaryColor

Color of a text displayed on an element whose color is primaryColor

#FFFFFF

fontColorOnSecondaryColor

Color of a text displayed on an element whose color is secondaryColor

#FFFFFF

backgroundViewColor

Background color

#FAFAFA

neutralColor

Color of the separating lines

#F0F0F0

warningColor

Warning color (non-critical hint)

#F7A334

criticalColor

Alert color (critical hint)

#E52027

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="primaryColor">#0B4D6E</color>
    <color name="secondaryColor">#77E2B0</color>
    <color name="mainFontColor">#161616</color>
    <color name="complementaryFontColor">#9E9E9E</color>
    <color name="fontColorOnPrimaryColor">@android:color/white</color>
    <color name="fontColorOnSecondaryColor">@android:color/white</color>
    <color name="backgroundViewColor">#FAFAFA</color>
    <color name="neutralColor">#F0F0F0</color>
    <color name="warningColor">#F7A334</color>
    <color name="criticalColor">#E52027</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font
        app:font="@font/sketchy"
        app:fontStyle="normal"
        app:fontWeight="400" /> <!-- Weight 400 = Normal (Regular) -->
    <font
        app:font="@font/deadknight"
        app:fontStyle="normal"
        app:fontWeight="700" /> <!-- Weight 700 = Bold -->
</font-family>
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font app:font="@font/stocky" />
</font-family>
DriveKitUI.configureAnalytics(object: DriveKitAnalyticsListener{
   override fun trackScreen(screen: String, className: String) {
       // TODO: manage screen tracking here
   }

   override fun trackEvent(event: DKAnalyticsEvent, parameters: Map<DKAnalyticsEventKey, String>) {
       // TODO: manage event tracking here
    }
})
DriveKitUI.configureAnalytics(new DriveKitAnalyticsListener() {
   @Override
   public void trackScreen(@NotNull String screen, @NotNull String className) {
       // TODO: manage screen tracking here
   }

   @Override
   public void trackEvent(@NotNull DKAnalyticsEvent event, @NotNull Map<DKAnalyticsEventKey, String> parameters) {
       // TODO: manage event tracking here
   }
});
CommonUI
target 'my-target' do
  pod 'DriveKitDriverData'
end
import DriveKitDriverDataModule
import DriveKitCoreModule
import DriveKitTripAnalysisModule

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    DriveKit.shared.initialize()
    DriveKitDriverData.shared.initialize()
    ...    
}
public func getTripsOrderByDateDesc(type: SynchronizationType = .defaultSync, completionHandler: @escaping (TripSyncStatus, [DKTrip]) -> ())
DriveKitDriverData.shared.getTripsOrderByDateDesc(completionHandler: { status, trips in
    // Check status and use trips data
})
public func getTrip(itinId: String, completionHandler: @escaping (TripSyncStatus, DKTrip?) -> ())
DriveKitDriverData.shared.getTrip(itinId: itinId, completionHandler: { status, trip in
    // Check status and use trip data
})
public func getRoute(itinId: String, completionHandler: @escaping (DKRoute?) -> ())
DriveKitDriverData.shared.getRoute(itinId: itinId, completionHandler: { route in
    if let route = route {
        // Use route data
     } else {
        // Failed to synchronize route
     }
})
 public func deleteTrip(itinId: String, completionHandler: @escaping (Bool) -> ())
DriveKitDriverData.shared.deleteTrip(itinId: self.viewModel.itinId, completionHandler: { deleteSuccessful in
    if deleteSuccessful {
        // trip successfully deleted
    } else {
        // Failed to delete trip
    }
})
public func getSynthesis(type: SynchronizationType = .cache, completionHandler: @escaping (SynthesisSyncStatus, DKSynthesis?) -> ())
import DriveKitDriverDataModule

DriveKitDriverData.shared.getSynthesis(type: .defaultSync) { status, synthesis in
    // Check status and use synthesis
}
public func getDriverTimelines(periods: [DKPeriod], type: SynchronizationType = .defaultSync, completionHandler: @escaping (TimelineSyncStatus, [DKDriverTimeline]?) -> Void)
import DriveKitDriverDataModule

DriveKitDriverData.shared.getTimelines(periods: [.week, .month], type: .defaultSync) { (status, timelines) in
    // Check status and use timelines
}
public func getDriverTimelines(
    periods: [DKPeriod],
    ignoreItemsWithoutTripScored: Bool = false,
    type: SynchronizationType = .defaultSync,
    completionHandler: @escaping (TimelineSyncStatus, [DKDriverTimeline]?) -> Void
)
import DriveKitDriverDataModule

DriveKitDriverData.shared.getDriverTimelines(periods: [.week, .month, .year], type: .defaultSync) { (status, timelines) in
    // Check status and use timelines
}
public func getDriverProfile(
   type: SynchronizationType = .defaultSync,
   completionHandler: @escaping (DKDriverProfileStatus, DKDriverProfile?) -> Void
)
import DriveKitDriverDataModule

DriveKitDriverData.shared.getDriverProfile(type: .defaultSync) { (status, driverProfile) in
    // Check status and use driverProfile
}

Screen key

Screen tag value

dk_tag_trips_list

drivekit-trips-list

dk_tag_trips_detail

drivekit-trips-detail

dk_tag_trips_detail_advice_safety

drivekit-trips-detail-advice-safety

dk_tag_trips_detail_advice_efficiency

drivekit-trips-detail-advice-efficiency

dk_tag_trips_detail_transportation_mode

drivekit-trips-detail-transportation_mode

dk_tag_badges

drivekit-badges

dk_tag_rankings

drivekit-rankings

dk_tag_streaks

drivekit-streaks

dk_tag_vehicles_list

drivekit-vehicles-list

dk_tag_vehicles_detail

drivekit-vehicles-detail

dk_tag_vehicles_add

drivekit-vehicles-add

dk_tag_vehicles_beacon_verify

drivekit-vehicles-beacon-verify

dk_tag_vehicles_beacon_add

drivekit-vehicles-beacon-add

dk_tag_vehicles_beacon_diagnosis

drivekit-vehicles-beacon-diagnosis

dk_tag_vehicles_beacon_info

drivekit-vehicles-beacon-info

dk_tag_vehicles_bluetooth_add

drivekit-vehicles-bluetooth-add

dk_tag_permissions_diagnosis

drivekit-permissions-diagnosis

dk_tag_permissions_onboarding

drivekit-permissions-onboarding

dk_tag_challenge_list_active

drivekit-challenge-list-active

dk_tag_challenge_list_finished

drivekit-challenge-list-finished

dk_tag_challenge_join

drivekit-challenge-join

dk_tag_challenge_detail

drivekit-challenge-detail

dk_tag_challenge_detail_results

drivekit-challenge-detail-results

dk_tag_challenge_detail_ranking

drivekit-challenge-detail-ranking

dk_tag_challenge_detail_trips

drivekit-challenge-detail-trips

dk_tag_challenge_detail_rules

drivekit-challenge-detail-rules

let metadata: [String: String] = [
    "key": "value"
]
DriveKitTripAnalysis.shared.setTripMetadata(metadata)
DriveKitTripAnalysis.shared.getTripMetadata()
DriveKitTripAnalysis.shared.updateTripMetadata(key: String, value: String?)
DriveKitTripAnalysis.shared.deleteTripMetadata(key: String)
DriveKitTripAnalysis.shared.deleteTripMetadata()
fun getBluetoothPairedDevices(): List<BluetoothData>
fun setBluetoothDevices(devices: List<BluetoothData>)
fun setBluetoothDeviceRequired(required: Boolean)
bluetooth device
required
fun addTripListener(listener: TripListener)
fun removeTripListener(listener: TripListener)
fun removeAllTripListeners()
fun getTripResponseStatus(tripResponse: PostGenericResponse): TripResponseStatus

Android

iOS

Android

Android

Speed Limit
SpeedingEvents
API level 23
Room library
Core Data
Github repository
Github
GitHub
in this array
initialized DriveKit
sdkStateChanged(state: State)
Trip recording lifecycle
Vehicle body type
Engine type
Gearbox type
Weather code
Transportation mode
Road conditions
Comment
ItineraryStatistics
ItineraryData
EcoDriving
AdvancedEcoDriving
FuelEstimation
AdvancedFuelEstimation
Safety
AdvancedSafety
SafetyEvent
TireWear
BrakeWear
Pollutants
DriverDistraction
DistractionEvents
CallEvent
EnergyEstimation
AdvancedEnergyEstimation
Energy Class
EcoDrivingContext
FuelEstimationContext
SafetyContext
Call
SpeedLimitContexts
DriveKit Demo App
disabled the SDK auto-initialization
disabled the SDK auto-initialization
Driver trips
DKTrip
trip
Trip
above
here
TripResult
TripResponseStatus
beacon
DKDriverTimeline
DKDriverProfile

iOS

tripRecordingStarted(state: DKTripRecordingStartedState)

Immediately called when a trip recording starts.

This callback is triggered:

  • after automatic trip detection.

tripRecordingConfirmed(state: DKTripRecordingConfirmedState)

tripRecordingCanceled(state: DKTripRecordingCanceledState)

Called when a trip recording is canceled. DKTripRecordingCanceledState indicates which event has canceled the trip.

tripRecordingFinished(state: DKTripRecordingFinishedState)

tripFinished(result: TripResult)

This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.

tripPoint(tripPoint: TripPoint)

tripSavedForRepost()

Called if at the end of the trip, the trip couldn't be sent to DriveQuant's server for the analysis, for example when the smartphone has no network. The trip is saved locally on the SDK and will automatically be sent later.

beaconDetected()

This method is called when a beacon sets in the SDK is detected.

sdkStateChanged(state: State)

crashDetected(crashInfo: DKCrashInfo)

crashFeedbackSent(crashInfo: DKCrashInfo, feedbackType: DKCrashFeedbackType, severity: DKCrashFeedbackSeverity)

Called each time a trip has started and is confirmed. StartMode indicates which event starts the trip.

tripFinished(post: PostGeneric, response: PostGenericResponse)

This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.

PostGeneric contains raw data sent to DriveQuant's server, PostGenericResponse object contains the trip analysis made on DriveQuant's server.

onDeviceConfigEvent(deviceConfigEvent: DeviceConfigEvent)

Get started

Prerequisite

If you use DriveKit Driver Data without having initialized DriveKit, an exception will be generated and the SDK will not work in your application.

Integration

Get module from repository

To add Driver Data module to your app, add the following line to your dependencies in your application build.gradle file:

dependencies {
    implementation 'com.drivequant.drivekit:drivekit-driver-data:$drivekit_version'
}

Replace $drivekit_version with the DriveKit version you are using in your app

Initialization

fun initialize()

Get driver trips

fun getTripsOrderByDateDesc(listener: TripsQueryListener, type: SynchronizationType = SynchronizationType.DEFAULT)

SynchronizationType can have 2 values:

  • DEFAULT: if this value is used, the SDK will try to synchronize local trips with DriveQuant backend to get new trips or modified trips, and then return the trip list via the completionHandler.

  • CACHE: if this value is used, no synchronization will be performed and only trips previously synchronized will be return via the completionHandler.

An implementation of TripsQueryListener must be provided in order to retrieve trips.

interface TripsQueryListener {
    fun onResponse(status: TripsSyncStatus, trips: List<Trip>)
}

The status in onResponse have one of the following values:

  • NO_ERROR: Synchronization has been successfully performed.

  • CACHE_DATA_ONLY: SynchronizationType has been set to CACHE.

  • FAILED_TO_SYNC_TRIPS: Synchronization has failed, only trips previously synchronized are returned.

  • SYNC_ALREADY_IN_PROGRESS : Another trip list synchronization is already in progress

Trips are returned and sorted by end date in descending order.

Example:

DriveKitDriverData.getTripsOrderByDateDesc(object: TripsQueryListener {
                override fun onResponse(status: TripsSyncStatus, trips: List<Trip>) {
                    // Check status and trips data
                }
            }, SynchronizationType.DEFAULT)

Get specific trip

fun getTrip(itinId: String, listener: TripQueryListener)

The itinId parameter is the unique identifier for a trip.

An implementation of TripQueryListener must be provided in order to retrieve the trip.

interface TripQueryListener {
    fun onResponse(status: TripsSyncStatus, trip: Trip?)
}

When you call this method, you will get trip data and trip safety events. If safety events are not synchronized locally for the trip, a synchronization with DriveQuant backend will be performed and then, the trip will be returned with safety events synchronized.

Example:

DriveKitDriverData.getTrip(itinId, object: TripQueryListener {
    override fun onResponse(status: TripsSyncStatus, trip: Trip?) {
        // Check status and use trip data
    }
})

Get trip road data

To get road data of the trip (latitude, longitude), you have to call the following method:

fun getRoute(itinId: String, listener: RouteQueryListener)

An implementation of RouteQueryListener must be provided in order to retrieve the trip.

interface RouteQueryListener {
    fun onResponse(status: RouteStatus, route: Route?)
}

RouteStatus can have 2 values:

  • NO_ERROR: The trip has been successfully retrieved.

  • FAILED_TO_RETRIEVE_ROUTE: Route has not been synchronized. route parameter will be null.

Example:

DriveKitDriverData.getRoute(itinId, object: RouteQueryListener {
    override fun onResponse(status: RouteStatus, route: Route?) {
        // Check status and use route data
    }
})

Delete a trip

To delete a trip, you have to call the following method:

fun deleteTrip(itinId: String, listener: TripDeleteQueryListener)

The itinId parameter is the unique identifier for a trip.

Example:

DriveKitDriverData.deleteTrip(itinId, object: TripDeleteQueryListener {
    override fun onResponse(status: Boolean) {
        if (status) {
            //Trip succesfully deleted
        } else {
            // Failed to delete trip
        }
    }
})

Get driver synthesis

To get driver synthesis data, you have to call the following method:

fun getSynthesis(
   listener: SynthesisQueryListener,
   synchronizationType: SynchronizationType)

An implementation of SynthesisQueryListener must be provided in order to retrieve synthesis data.

interface SynthesisQueryListener {
fun onResponse(synthesisStatus: SynthesisStatus, synthesis: Synthesis?)
}

SynthesisStatus in the callback can have 3 values:

  • NO_ERROR: Synchronization has been successfully performed.

  • CACHE_DATA_ONLY: SynchronizationType has been set to cache.

  • FAILED_TO_SYNC_SYNTHESIS_CACHE_ONLY: Synchronization has failed, only data retrieved during the last synchronisation are returned.

Example:

DriveKitDriverData.getSynthesis(object : SynthesisQueryListener {
    override fun onResponse(
        synthesisStatus: SynthesisStatus,
        synthesis: Synthesis?
    ) {
        // Check synthesisStatus and use synthesis data
    }
})
DriveKitDriverData.INSTANCE.getSynthesis(new SynthesisQueryListener() {
            @Override
            public void onResponse(@NotNull SynthesisStatus synthesisStatus,                    @Nullable Synthesis synthesis) {
                  // Check synthesisStatus and use synthesis data
            }
        }, SynchronizationType.DEFAULT);

Get driver timelines

To get driver timelines, you have to call the following method:

fun getDriverTimelines(
        periods: List<DKPeriod>,
        synchronizationType: SynchronizationType = SynchronizationType.DEFAULT,
        ignoreItemsWithoutTripScored: Boolean = false,
        callback: (timelineSyncStatus: TimelineSyncStatus, timelines: List<DKDriverTimeline>) -> Unit
)
Parameter name
Type
Description

periods

DKTimelinePeriod

Get timeline data in a specific period of time. Possible values are : WEEK, MONTH, YEAR.

synchronizationType

SynchronizationType

Define the source of the timelines data you want to retrieve. Possible values are: CACHE: No sync will be performed and the data retrieved during the last sync will be returned via the callback.

DEFAULT: the SDK will try to synchronize timelines with DriveQuant backend and then return them via the callback.

ignoreItemsWithoutTripScored

Boolean

The TimelineSyncStatus enum values are:

  • CACHE_DATA_ONLY: SynchronizationType has been set to CACHE.

  • NO_ERROR: Sync has been successfully performed.

  • FAILED_TO_SYNC_TIMELINE_CACHE_ONLY: Sync has failed, only data retrieved during the last sync are returned.

  • NO_TIMELINE_YET: Sync has been successfully performed and there is currently no timeline.

Get driver profile

To get driver profile, you have to call the following method:

fun getDriverProfile(
    synchronizationType: SynchronizationType = SynchronizationType.DEFAULT,
    callback: (status: DKDriverProfileStatus, driverProfile: DKDriverProfile?) -> Unit
)

SynchronizationType can have 2 values:

  • DEFAULT: if this value is used, the SDK will try to synchronize the driver profile with DriveQuant backend and then return it via the completionHandler.

  • CACHE: if this value is used, no synchronisation will be performed and the data retrieved during the last synchronisation will be returned via the callback.

DKDriverProfileStatus in the callback can take 4 values:

  • SUCCESS: Synchronization type has been successfully performed.

  • FAILED_TO_SYNC_DRIVER_PROFILE_CACHE_ONLY: Synchronisation has failed, only data retrieved during the last synchronisation is returned.

  • NO_DRIVER_PROFILE_YET: Synchronisation has been successfully performed and there is currently no driver profile for this user.

  • FORBIDDEN_ACCESS: Your team doesn’t have access to this data.

Example:

import com.drivequant.drivekit.driverdata.DriveKitDriverData

DriveKitDriverData.getDriverProfile(type: DKDriverProfileStatus.DEFAULT) { status, driverProfile ->
    // Check status and use driverProfile
}
import com.drivequant.drivekit.core.SynchronizationType;
import com.drivequant.drivekit.driverdata.DriveKitDriverData;

DriveKitDriverData.INSTANCE.getDriverProfile(SynchronizationType.DEFAULT, (dkDriverProfileStatus, dkDriverProfile) -> {
    // Check status and use driverProfile
    return null;
});

Get started

Prerequisite

Integration

Get the framework

The Driver Data UI SDK is available on Cocoapods master repo.

To access the framework in the repository, add the following lines to your Podfile:

target 'my-target' do
  pod 'DriveKitDriverDataUI'
end

Then, run pod install.

Initialization

import DriveKitDriverDataUI

Then, to initialize Driver Data UI SDK in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate:

import DriveKitCore
import DriveKitCommonUI
import DriveKitDriverData
import DriveKitDriverDataUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    DriveKit.shared.initialize()
    DriveKitDriverData.shared.initialize()
    DriveKitUI.shared.initialize()
    DriveKitDriverDataUI.shared.initialize()
    ...    
}

Override colors and texts

Trip list main theme

It is possible to choose the main theme for the trip list. The main theme of the trip list is used to select the score to be displayed on the left side of the trip list. It is set by the TripData enum. It has 6 possible values:

  • .safety : The driving safety score.

  • .ecoDriving : The eco-driving score.

  • .distraction : The driving distraction score.

  • .distance : The trip distance.

  • .duration : The driving duration.

  • .speeding : The speeding score.

The value .speeding can be set only if this configuration is enabled for your API key.

The main theme is configured in the SDK initialize method by setting the parameter tripData.

DriveKitDriverDataUI.shared.initialize(tripData: .safety)

The default value is safety.

Trip map items

A trip is analyzed through several dimensions and DriveQuant's services provide multiple categories of scores. Depending on your need, you can highlight the scores of interest and hide some of them. The configuration of the trip detail screen allows to choose the displayed themes and the displaying order. To switch from one theme to another, simply swipe the bottom part of the screen or click on one of the pictograms in the navigation bar at the top of the screen.

The screens that can be displayed are listed below:

  • The safety analysis results: .safety.

  • The eco-driving results: .ecoDriving.

  • The distracted driving results: .distraction.

  • The speeding driving results: .speeding.

  • A scrollable list that displays all the events that occurred during the trip: .interactiveMap.

  • Synthetic data of the trip as average speed, CO2 emissions, estimated fuel consumption, driving conditions : .synthesis.

The value .speeding can be set only if this configuration is activated on your team.

The main theme is configured in the SDK initialize method by setting the parameter mapItems.

DriveKitDriverDataUI.shared.initialize(mapItems: [.safety, .ecoDriving, .distraction, .speeding, .interactiveMap, .synthesis])

The default value is:

[.safety, .ecoDriving, .distraction, .speeding, .interactiveMap, .synthesis]

The order in which the screens are displayed corresponds to the order of the items in the table. To hide a theme, simply do not add it to the table.

Display view in navigation controller

To show view in your navigation controller, you just have to create an instance of TripListVC and then push the view controller in your navigation controller.

let tripListVC = TripListVC()
self.navigationController?.pushViewController(tripListVC, animated: true)

References (iOS)

DKDriverTimeline

DKDriverTimeline is an object that contains timeline data for the given period.

public struct DKDriverTimeline: Codable {
    public let period: DKPeriod
    public let allContext: [DKAllContextItem]
    public let roadContexts: [DKRoadContext: [DKRoadContextItem]]
}
Attribute
Type
Description

period

The kind of aggregation period for this timeline

allContext

The list of all global context sorted by date

roadContexts

The dictionary of all road context and their associated list of context data sorted by date

DKPeriod

DKPeriod indicates the aggregation size of each timeline object. It is an enum with the following values:

Value
Description

week

Timeline data is aggregated week by week

month

Timeline data is aggregated month by month

year

Timeline data is aggregated year by year

public enum DKPeriod: Int, Codable {
    case week
    case month
    case year
}

DKAllContextItem

DKAllContextItem is an object that contains data for global context for the given period.

public struct DKAllContextItem: Codable {
    public let date: Date
    public let numberTripTotal: Int
    public let numberTripScored: Int
    public let distance: Double
    public let duration: Int

    public var safety: DKSafety?
    public var ecoDriving: DKEcoDriving?
    public var phoneDistraction: DKDistraction?
    public var speeding: DKSpeeding?
    public var drivingConditions: DKDrivingConditions?
}
Attribute
Type
Description

date

Date

Start date of the given period

numberTripTotal

Int

Total number of trips made during the given period

numberTripScored

Int

Number of trips made that were long enough to have a score during the given period

distance

Double

Total distance travelled during the given period (in kilometers)

duration

Int

Total trip duration during the given period (in minutes)

safety

Safety's score and sub scores for the given period (present only if safety score is configured and the period has some scored trips)

ecoDriving

Eco-driving's score and sub scores for the given period (present only if eco-driving score is configured and the period has some scored trips)

phoneDistraction

Distraction's score and sub scores for the given period (present only if distraction score is configured)

speeding

Speeding's score and sub scores for the given period (present only if speeding score is configured)

drivingConditions

Advanced informations for a given period (total trip and distance for a specific DKDrivingCategory and by DKWeather, distance travelled by day/night and by weekdays/weekend)

DKSafety

DKSafety is an object that contains data for safety's score and sub scores.

public struct DKSafety: Codable {
    public let score: Double
    public let acceleration: Int
    public let braking: Int
    public let adherence: Int
}
Attribute
Type
Description

score

Double

Global safety score for the given period (ranging from 3 to 10)

acceleration

Int

Number of harsh accelerations during the given period

braking

Int

Number of hard breakings during the given period

adherence

Int

Number of adherence limits during the given period

DKEcoDriving

DKEcoDriving is an object that contains data for eco-driving's score and sub scores.

public struct DKEcoDriving: Codable {
    public let score: Double
    public let efficiencyAcceleration: Double
    public let efficiencyBrake: Double
    public let efficiencySpeedMaintain: Double
    public let fuelVolume: Double
    public let fuelSaving: Double
    public let co2Mass: Double
}
Attribute
Type
Description

score

Double

Global eco-driving score for the given period (ranging from 6 to 10)

efficiencyAcceleration

Double

Sub score of acceleration efficiency for the given period (ranging from -5 to 5)

efficiencyBrake

Double

Sub score of braking efficiency for the given period (ranging from -5 to 5)

efficiencySpeedMaintain

Double

Sub score of speed maintain efficiency for the given period (ranging from 0 to 5)

fuelVolume

Double

Fuel consumption during the given period (in liters)

fuelSaving

Double

Achievable fuel savings during the given period (in liters)

co2Mass

Double

CO₂ mass consumed during the given period (in kilograms)

DKDistraction

DKDistraction is an object that contains data for distraction's score and sub scores.

public struct DKDistraction: Codable {
    public let score: Double
    public let unlock: Int
    public let lock: Int
    public let callForbiddenDuration: Int
    public let numberTripWithForbiddenCall: Int
    public let callForbidden: Int
    public let callAuthorizedDuration: Int
    public let callAuthorized: Int
}
Attribute
Type
Description

score

Double

Global distraction score for the given period (ranging from 0 to 10)

unlock

Int

Number of screen unlocks during the given period

lock

Int

Number of screen locks during the given period

callForbiddenDuration

Int

Duration of forbidden calls during the given period (in seconds)

numberTripWithForbiddenCall

Int

Number of trips during which the driver made forbidden calls during the given period

callForbidden

Int

Number of forbidden calls during the given period

callAuthorizedDuration

Int

Duration of authorized calls during the given period (in seconds)

callAuthorized

Int

Number of authorized calls during the given period

DKSpeeding

DKSpeeding is an object that contains data for speeding's score and sub scores.

public struct DKSpeeding: Codable {
    public let score: Double
    public let speedingDuration: Int
    public let speedingDistance: Double
}
Attribute
Type
Description

score

Double

Global speeding score for the given period (ranging from 0 to 10)

speedingDuration

Int

Overspeeding duration during the given period (in seconds)

speedingDistance

Double

Overspeeding distance travelled during the given period (in meters)

DKDrivingConditions

DKDrivingConditions is an object that contains advanced driving information for the given period.

public struct DKDrivingConditions: Codable {
        public let tripCountByCategory: [DKDrivingCategory: Int]
        public let distanceByCategory: [DKDrivingCategory: Double]
        public let tripCountByWeatherType: [DKWeather: Int]
        public let distanceByWeatherType: [DKWeather: Double]
        public let dayDistance: Double
        public let nightDistance: Double
        public let weekdaysDistance: Double
        public let weekendDistance: Double
}
Attribute
Type
Description

tripCountByCategory

Total trips count by driving category

distanceByCategory

Total distance in km by driving category

tripCountByWeatherType

Total trips count by weather category

distanceByWeatherType

Total distance in km count by weather category

dayDistance

Double

Total distance traveled by the day in km

nightDistance

Double

Total distance traveled by night in km

weekdaysDistance

Double

Total distance traveled during weekdays in km

weekendDistance

Double

Total distance traveled during weekend in km

DKDrivingCategory

public enum DKDrivingCategory: Int, Codable {
    case lessThan2Km = 0
    case from2To10Km = 1
    case from10To50Km = 2
    case from50To100Km = 3
    case moreThan100Km = 4
}
Attribute
Description

lessThan2Km

Trip distance strictly below 2 km

from2To10Km

Trip distance in [2, 10[ km

from10To50Km

Trip distance in [10, 50[ km

from50To100Km

Trip distance in [50, 100[ km

moreThan100Km

Trip distance is equals or above 100 km

DKRoadContextItem

DKRoadContextItem is an object that contains data for the given road context and given period.

public struct DKRoadContextItem: Codable {
    public let type: DKRoadContext
    public let date: Date
    public let numberTripTotal: Int
    public let numberTripScored: Int
    public let distance: Double
    public let duration: Int
    
    public var ecoDriving: DKEcoDriving?
    public var safety: DKSafety?
}
Attribute
Type
Description

type

Road context for the given period

date

Date

Start date of the given period

numberTripTotal

Int

Total number of trips made during the given period and road context

numberTripScored

Int

Number of trips made that were long enough to have a score during the given period and road context

distance

Double

Total distance travelled during the given period and road context (in kilometers)

duration

Int

Total trip duration during the given period and road context (in minutes)

safety

Safety's score and sub scores for the given period and road context (present only if safety score is configured and the period has some scored trips)

ecoDriving

Eco-driving's score and sub scores for the given period and road context (present only if eco-driving score is configured and the period has some scored trips)

DKRoadContext

DKRoadContext indicates the kind of roads where the data was gathered. It is an enum with the following values:

Value
Description

trafficJam

The targeted driver was in traffic jams

heavyUrbanTraffic

The targeted driver was in dense city roads

city

The targeted driver was in light traffic city roads

suburban

The targeted driver was in suburban or countryside roads

expressways

The targeted driver was in express ways

public enum DKRoadContext: Int, Codable {
    case trafficJam
    case heavyUrbanTraffic
    case city
    case suburban
    case expressways
}


DKDriverProfile

DKDriverProfile is the object describing the driver profile.

Attribute
Type
Description

distance

Distance class

activity

Activity class

regularity

Regularity class

mainRoadContext

Main road context

mobility

Mobility class

statistics

Statistics about the driver

weekRegularity

Information about driver’s week regularity

monthRegularity

Information about driver’s month regularity

distanceEstimation

Distance estimation by week, month or year

roadContextInfoByRoadContext

Contains information about road contexts

commonTripByType

Provides information about common trips, by type of trip

mobilityAreaRadiusByType

Provides radius of mobility area by type of mobility

public struct DKDriverProfile: Codable {
    public var distance: DKDistanceProfile
    public var activity: DKActivityProfile
    public var regularity: DKRegularityProfile
    public var mainRoadContext: DKRoadContext
    public var mobility: DKMobilityProfile
    public var statistics: DKDriverStatistics
    public var weekRegularity: DKDriverRegularity
    public var monthRegularity: DKDriverRegularity
    public var distanceEstimation: DKDriverDistanceEstimation
    public var roadContextInfoByRoadContext: [DKRoadContext: DKRoadContextInfo]
    public var commonTripByType: [DKCommonTripType: DKCommonTrip]
    public var mobilityAreaRadiusByType: [DKMobilityAreaType: Int]
}

DKDistanceProfile

DKDistanceProfile indicates the distance class of the driver.

Value
Description
Estimated yearly distance (in km)

.veryShort

Very short distance driver

less than 5 000

.short

Short distance driver

5 000 to 10 000

.medium

Medium distance driver

10 000 to 20 000

.long

Long distance driver

20 000 to 40 000

.veryLong

Professional driver

more than 40 000

public enum DKDistanceProfile: String, Codable {
    case veryShort = "VERY_SHORT"
    case short = "SHORT"
    case medium = "MEDIUM"
    case long = "LONG"
    case veryLong = "VERY_LONG"
}

DKActivityProfile

DKActivityProfile indicates the activity class of the driver.

Value
Description
Percentage of active weeks

.low

Low activity driver

less than 30 %

.medium

Medium activity driver

30 to 60 %

.high

High activity driver

more than 60 %

public enum DKActivityProfile: String, Codable {
    case low = "LOW"
    case medium = "MEDIUM"
    case high = "HIGH"
}

DKRegularityProfile

DKRegularityProfile indicates the regularity class of the driver.

Value
Description

.regular

Regular driver

.intermittent

Intermittent driver

public enum DKRegularityProfile: String, Codable {
    case regular = "REGULAR"
    case intermittent = "INTERMITTENT"
}

DKMobilityProfile

DKMobilityProfile indicates the mobility class of the driver.

Value
Description

.narrow

90% of trips are within a radius of less than 10 km

.small

90% of trips are within a radius of less than 20 km

.medium

90% of trips are within a radius of less than 30 km

.large

90% of trips are within a radius of less than 50 km

.wide

90% of trips are within a radius of less than 100 km

.vast

90% of trips are within a radius of 100 km or more

public enum DKMobilityProfile: String, Codable {
    case narrow = "NARROW"
    case small = "SMALL"
    case medium = "MEDIUM"
    case large = "LARGE"
    case wide = "WIDE"
    case vast = "VAST"
}

DKDriverStatistics

DKDriverStatistics is an object providing statistics about the driver.

Attribute
Type
Description

tripsNumber

Int

Total number of trips

totalDistance

Int

Total distance (in km)

totalDuration

Int

Total driving duration (in min)

weekNumber

Int

Number of weeks since user registration

activeWeekNumber

Int

Number of active weeks since user registration

monthNumber

Int

Number of months since user registration

activeMonthNumber

Int

Number of active months since user registration

peakTime

DKTime

Peak time trip starts

peakDay

DKDay

Weekday with most trips completed

public struct DKDriverStatistics: Codable {
    public var tripsNumber: Int
    public var totalDistance: Int
    public var totalDuration: Int
    public var weekNumber: Int
    public var activeWeekNumber: Int
    public var monthNumber: Int
    public var activeMonthNumber: Int
    public var peakTime: DKTime
    public var peakDay: DKDay
}

DKDriverRegularity

DKDriverRegularity is an object providing information about driver’s regularity.

Attribute
Type
Description

periodNumber

Int

Number of weeks or months used to calculate regularity

tripNumberMean

Int

Average number of trips per week or month

tripNumberStandardDeviation

Int

Standard deviation of the number of trips per week or month

distanceMean

Int

Average weekly or monthly distance (in km)

distanceStandardDeviation

Int

Standard deviation of the weekly or monthly distance (in km)

durationMean

Int

Average weekly or monthly driving duration (in min)

durationStandardDeviation

Int

Standard deviation of the weekly or monthly driving duration (in min)

public struct DKDriverRegularity: Codable {
    public var periodNumber: Int
    public var tripNumberMean: Int
    public var tripNumberStandardDeviation: Int
    public var distanceMean: Int
    public var distanceStandardDeviation: Int
    public var durationMean: Int
    public var durationStandardDeviation: Int
}

DKDriverDistanceEstimation

DKDriverDistanceEstimation is an object providing distance estimation by week, month or year.

Attribute
Type
Description

weekDistance

Int

Estimated weekly distance (in km)

monthDistance

Int

Estimated monthly distance (in km)

yearDistance

Int

Estimated annual distance (in km)

confidence

Confidence level indicator, based on the available data

public struct DKDriverDistanceEstimation: Codable {
    public var weekDistance: Int
    public var monthDistance: Int
    public var yearDistance: Int
    public var confidence: DKDriverDistanceEstimationConfidence
}

DKDriverDistanceEstimationConfidence

DKDriverDistanceEstimationConfidence indicates the distance estimation confidence class.

Value
Description

.low

If less than 8 weeks since driver’s subscription

.medium

If between 9 and 16 weeks since driver’s subscription

.high

If more than 16 weeks since driver’s subscription

public enum DKDriverDistanceEstimationConfidence: String, Codable {
    case low = "LOW"
    case medium = "MEDIUM"
    case high = "HIGH"
}

DKRoadContextInfo

DKRoadContextInfo is an object providing information about road context for the driver.

Attribute
Type
Description

roadContext

Road context

distancePercentage

Double

Percentage of total distance driven in this context

durationPercentage

Double

Percentage of total duration driven in this context

consumedEnergyPercentage

Double

Percentage of total energy driven in this context

public struct DKRoadContextInfo: Codable {
    public var roadContext: DKRoadContext
    public var distancePercentage: Double
    public var durationPercentage: Double
    public var consumedEnergyPercentage: Double
}

DKCommonTripType

DKCommonTripType indicates the type of trip.

Value
Description

.mostFrequent

Most frequent trip

.unknown

Unknown type for the SDK (if a new type is added but the SDK is not up to date)

public enum DKCommonTripType: String, Codable {
    case mostFrequent = "MOST_FREQUENT"
    case unknown = "UNKNOWN"
}

DKCommonTrip

DKCommonTrip is an object providing information about a trip.

Attribute
Type
Description

type

Type of trip

tripNumber

Int

Number of trips

distanceMean

Int

Average trip distance (in km)

durationMean

Int

Average trip duration (in min)

roadContext

Road context type

public struct DKCommonTrip: Codable {
    public var type: DKCommonTripType
    public var tripNumber: Int
    public var distanceMean: Int
    public var durationMean: Int
    public var roadContext: DKRoadContext
}

DKMobilityAreaType

DKMobilityAreaType indicates the type of mobility area.

Value
Description

.percentile50Th

The radius including 50% of all the user’s trips

.percentile90Th

The radius including 90% of all the user’s trips

public enum DKMobilityAreaType: String, Codable {
    case percentile50Th = "PERCENTILE_50TH"
    case percentile90Th = "PERCENTILE_90TH"
}

User interface

Driver’s trips

Driver Data component includes an open source graphics library which provides a set of screens to display trip data recorded by the Trip Analysis component and analyzed by DriveQuant services.

The Driver Data component displays the list of trips made by the driver as well as the details of each trip displayed on a map with all driving indicators and driver scores.

Driver Data component gives a direct access to the formatted data on simple and readable screens. This way, you do not need to create specific screens in your application for illustrating driver’s trip analytics.

All the screens that display the trip results are fully customizable. You can configure the information you want to highlight and integrate styling elements from your application such as colors and fonts. The configuration options are detailed later in this section.

The use of this graphic library is not mandatory and you can develop your own screens if their actual style doesn't fit with your mobile application. In this case, the graphics library can be used as an example to design your own visualizations.

Trips widgets

The Driver data component includes 2 cards that simplifies the display of driver behaviour scores synthesis:

  1. The driver synthesis scorecard → shows the averages of each of the driving scores calculated over a 7 days since the last trip date.

  2. The last trip widget → displays a short chronological list of the driver's last trips.

My Synthesis

Driver Data Component provides a screen, “My synthesis”, where a driver can compare his average performances per week, month or year with reference levels and also with other drivers in the same community.

My Driver Profile

Each driver has a profile that corresponds to his habits. The driver's profile is determined from a statistical and historical analysis of his driving data:

  • how frequently the driver uses his car,

  • his regularity,

  • the most travelled road context,

  • the annual distance covered,

  • and his mobility area.

These information can be displayed to the driver thanks to the Driver Data graphical component of the DriveKit SDK.

References (Android)

DKDriverTimeline

DKDriverTimeline is an object that contains timeline data for the given period.

data class DKDriverTimeline(
    val period: DKPeriod,
    val allContext: List<DKAllContextItem>,
    val roadContexts: Map<RoadContext, List<DKRoadContextItem>>
) : Serializable

Attribute

Type

Description

period

The kind of aggregation period for this timeline

allContext

The list of all global context sorted by date

roadContexts

The map of all road context and their associated list of context data sorted by date

DKPeriod

DKPeriod indicates the aggregation size of each timeline object. It is an enum with the following values:

WEEK

Timeline data is aggregated week by week

MONTH

Timeline data is aggregated month by month

YEAR

Timeline data is aggregated year by year

enum class DKPeriod: Serializable {
    WEEK, MONTH, YEAR
}

DKAllContextItem

DKAllContextItem is an object that contains data for global context for the given period.

data class DKAllContextItem(
        override val date: Date,
        val numberTripScored: Int,
        val numberTripTotal: Int,
        val distance: Double,
        val duration: Int,
        val safety: DKSafety?,
        val ecoDriving: DKEcoDriving?,
        val phoneDistraction: DKDistraction?,
        val speeding: DKSpeeding?,
        val drivingConditions: DKDrivingConditions?
) : Serializable, DatedContextItem

Attribute

Type

Description

date

Date

Start date of the given period

numberTripTotal

Int

Total number of trips made during the given period

numberTripScored

Int

Number of trips made that were long enough to have a score during the given period

distance

Double

Total distance travelled during the given period (in kilometers)

duration

Int

Total trip duration during the given period (in minutes)

safety

Safety's score and sub scores for the given period (present only if safety score is configured and the period has some scored trips)

ecoDriving

Eco-driving's score and sub scores for the given period (present only if eco-driving score is configured and the period has some scored trips)

phoneDistraction

Distraction's score and sub scores for the given period (present only if distraction score is configured)

speeding

Speeding's score and sub scores for the given period (present only if speeding score is configured)

drivingConditions

Advanced informations for a given period (total trip and distance for a specific DKDrivingCategory and by DKWeather, distance travelled by day/night and by weekdays/weekend)

DKSafety

DKSafety is an object that contains data for safety's score and sub scores.

data class DKSafety(
        val score: Double,
        val acceleration: Int,
        val braking: Int,
        val adherence: Int
) : Serializable
Attribute
Type
Description

score

Double

Global safety score for the given period (ranging from 3 to 10)

acceleration

Int

Number of harsh accelerations during the given period

braking

Int

Number of hard breakings during the given period

adherence

Int

Number of adherence limits during the given period

DKEcoDriving

DKEcoDriving is an object that contains data for eco-driving's score and sub scores.

data class DKEcoDriving(
        val score: Double,
        val efficiencyBrake: Double,
        val efficiencyAcceleration: Double,
        val efficiencySpeedMaintain: Double,
        val co2Mass: Double,
        val fuelVolume: Double,
        val fuelSaving: Double
) : Serializable
Attribute
Type
Description

score

Double

Global eco-driving score for the given period (ranging from 4 to 10)

efficiencyAcceleration

Double

Sub score of acceleration efficiency for the given period (ranging from -5 to 5)

efficiencyBrake

Double

Sub score of braking efficiency for the given period (ranging from -5 to 5)

efficiencySpeedMaintain

Double

Sub score of speed maintain efficiency for the given period (ranging from 0 to 5)

fuelVolume

Double

Fuel consumption during the given period (in liters)

fuelSaving

Double

Achievable fuel savings during the given period (in liters)

co2Mass

Double

CO₂ mass consumed during the given period (in kilograms)

DKDistraction

DKDistraction is an object that contains data for distraction's score and sub scores.

data class DKDistraction(
        val score: Double,
        val unlock: Int,
        val lock: Int,
        val callAuthorized: Int,
        val callForbidden: Int,
        val callAuthorizedDuration: Int,
        val callForbiddenDuration: Int,
        val numberTripWithForbiddenCall: Int
) : Serializable
Attribute
Type
Description

score

Double

Global distraction score for the given period (ranging from 0 to 10)

unlock

Int

Number of screen unlocks during the given period

lock

Int

Number of screen locks during the given period

callForbiddenDuration

Int

Duration of forbidden calls during the given period (in seconds)

numberTripWithForbiddenCall

Int

Number of trips during which the driver made forbidden calls during the given period

callForbidden

Int

Number of forbidden calls during the given period

callAuthorizedDuration

Int

Duration of authorised calls during the given period (in seconds)

callAuthorized

Int

Number of authorised calls during the given period

DKSpeeding

DKSpeeding is an object that contains data for speeding's score and sub scores.

data class DKSpeeding(
    val score: Double,
    val speedingDuration: Int,
    val speedingDistance: Double,
) : Serializable
Attribute
Type
Description

score

Double

Global speeding score for the given period (ranging from 0 to 10)

speedingDuration

Int

Overspeeding duration during the given period (in seconds)

speedingDistance

Double

Overspeeding distance travelled during the given period (in meters)

DKDrivingConditions

DKDrivingConditions is an object that contains advanced driving information for the given period.

data class DKDrivingConditions (
    val tripCountByCategory: Map<DKDrivingCategory, Int>,
    val distanceByCategory: Map<DKDrivingCategory, Double>,
    val tripCountByWeatherType: Map<DKWeather, Int>,
    val distanceByWeatherType: Map<DKWeather, Double>,
    val dayDistance: Double,
    val nightDistance: Double,
    val weekdaysDistance: Double,
    val weekendDistance: Double
) : Serializable
Attribute
Type
Description

tripCountByCategory

Total trips count by driving category

distanceByCategory

Total distance in km by driving category

tripCountByWeatherType

Total trips count by weather category

distanceByWeatherType

Total distance in km count by weather category

dayDistance

Double

Total distance traveled by the day in km

nightDistance

Double

Total distance traveled by night in km

weekdaysDistance

Double

Total distance traveled during weekdays in km

weekendDistance

Double

Total distance traveled during weekend in km

DKDrivingCategory

enum class DKDrivingCategory(val index: Int) {
    LESS_THAN_2_KM(0),
    FROM_2_TO_10_KM(1),
    FROM_10_TO_50_KM(2),
    FROM_50_TO_100_KM(3),
    MORE_THAN_100_KM(4);
}
Attribute
Description

LESS_THAN_2_KM

Trip distance strictly below 2 km

FROM_2_TO_10_KM

Trip distance in [2, 10[ km

FROM_10_TO_50_KM

Trip distance in [10, 50[ km

FROM_50_TO_100_KM

Trip distance in [50, 100[ km

MORE_THAN_100_KM

Trip distance is equals or above 100 km

DKRoadContextItem

DKRoadContextItem is an object that contains data for the given road context and given period.

data class DKRoadContextItem(
        val type: RoadContext,
        override val date: Date,
        val numberTripTotal: Int,
        val numberTripScored: Int,
        val distance: Double,
        val duration: Int,
        val safety: DKSafety?,
        val ecoDriving: DKEcoDriving?
) : Serializable, DatedContextItem
Attribute
Type
Description

type

Road context for the given period

date

Date

Start date of the given period

numberTripTotal

Int

Total number of trips made during the given period and road context

numberTripScored

Int

Number of trips made that were long enough to have a score during the given period and road context

distance

Double

Total distance travelled during the given period and road context (in kilometers)

duration

Int

Total trip duration during the given period and road context (in minutes)

safety

Safety's score and sub scores for the given period and road context (present only if safety score is configured and the period has some scored trips)

ecoDriving

Eco-driving's score and sub scores for the given period and road context (present only if eco-driving score is configured and the period has some scored trips)

RoadContext

RoadContext indicates the kind of roads where the data was gathered. It is an enum with the following values:

Value
Description

TRAFFIC_JAM

The targeted driver was in traffic jams

HEAVY_URBAN_TRAFFIC

The targeted driver was in dense city roads

CITY

The targeted driver was in light traffic city roads

SUBURBAN

The targeted driver was in suburban or countryside roads

EXPRESSWAYS

The targeted driver was in express ways

enum class RoadContext : Serializable {
    EXPRESSWAYS, HEAVY_URBAN_TRAFFIC, CITY, SUBURBAN, TRAFFIC_JAM
}


DKDriverProfile

DKDriverProfile is the object describing the driver profile.

Attribute
Type
Description

distance

Distance class

activity

Activity class

regularity

Regularity class

mainRoadContext

Main road context

mobility

Mobility class

statistics

Statistics about the driver

weekRegularity

Information about driver’s week regularity

monthRegularity

Information about driver’s month regularity

distanceEstimation

Distance estimation by week, month or year

roadContextInfoByRoadContext

Contains information about road contexts

commonTripByType

Provides information about common trips, by type of trip

mobilityAreaRadiusByType

Provides radius of mobility area by type of mobility

@Keep
data class DKDriverProfile(
    val distance: DKDistanceProfile,
    val activity: DKActivityProfile,
    val regularity: DKRegularityProfile,
    val mainRoadContext: RoadContext,
    val mobility: DKMobilityProfile,
    val statistics: DKDriverStatistics,
    val weekRegularity: DKDriverRegularity,
    val monthRegularity: DKDriverRegularity,
    val distanceEstimation: DKDriverDistanceEstimation,
    val roadContextInfoByRoadContext: Map<RoadContext, DKRoadContextInfo>,
    val commonTripByType: Map<DKCommonTripType, DKCommonTrip>,
    val mobilityAreaRadiusByType: Map<DKMobilityAreaType, Int>
)

DKDistanceProfile

DKDistanceProfile indicates the distance class of the driver.

Value
Description
Estimated yearly distance (in km)

VERY_SHORT

Very short distance driver

less than 5000

SHORT

Short distance driver

5000 to 10000

MEDIUM

Medium distance driver

10000 to 20 000

LONG

Long distance driver

20 000 to 40 000

VERY_LONG

Professional driver

more than 40 000

@Keep
enum class DKDistanceProfile {
    VERY_SHORT,
    SHORT,
    MEDIUM,
    LONG,
    VERY_LONG
}

DKActivityProfile

DKActivityProfile indicates the activity class of the driver.

Value
Description
Percentage of active weeks

LOW

Low activity driver

less than 30 %

MEDIUM

Medium activity driver

30 to 60 %

HIGH

High activity driver

more than 60 %

@Keep
enum class DKActivityProfile {
    LOW,
    MEDIUM,
    HIGH
}

DKRegularityProfile

DKRegularityProfile indicates the regularity class of the driver.

Value
Description

REGULAR

Regular driver

INTERMITTENT

Intermittent driver

@Keep
enum class DKRegularityProfile {
    REGULAR,
    INTERMITTENT
}

DKMobilityProfile

DKMobilityProfile indicates the mobility class of the driver.

Value
Description

NARROW

90% of trips are within a radius of less than 10 km

SMALL

90% of trips are within a radius of less than 20 km

MEDIUM

90% of trips are within a radius of less than 30 km

LARGE

90% of trips are within a radius of less than 50 km

WIDE

90% of trips are within a radius of less than 100 km

VAST

90% of trips are within a radius of 100 km or more

@Keep
enum class DKMobilityProfile {
    NARROW,
    SMALL,
    MEDIUM,
    LARGE,
    WIDE,
    VAST
}

DKDriverStatistics

DKDriverStatistics is an object providing statistics about the driver.

Attribute
Type
Description

tripsNumber

Int

Total number of trips

totalDistance

Int

Total distance (in km)

totalDuration

Int

Total driving duration (in min)

weekNumber

Int

Number of weeks since user registration

activeWeekNumber

Int

Number of active weeks since user registration

monthNumber

Int

Number of months since user registration

activeMonthNumber

Int

Number of active months since user registration

peakTime

DKTime

Peak time trip starts

peakDay

DKDay

Weekday with most trips completed

@Keep
data class DKDriverStatistics(
    val tripsNumber: Int,
    val totalDistance: Int,
    val totalDuration: Int,
    val weekNumber: Int,
    val activeWeekNumber: Int,
    val monthNumber: Int,
    val activeMonthNumber: Int,
    val peakTime: DKTime,
    val peakDay: DKDay
)

DKDriverRegularity

DKDriverRegularity is an object providing information about driver’s regularity.

Attribute
Type
Description

periodNumber

Int

Number of weeks or months used to calculate regularity

tripNumberMean

Int

Average number of trips per week or month

tripNumberStandardDeviation

Int

Standard deviation of the number of trips per week or month

distanceMean

Int

Average weekly or monthly distance (in km)

distanceStandardDeviation

Int

Standard deviation of the weekly or monthly distance (in km)

durationMean

Int

Average weekly or monthly driving duration (in min)

durationStandardDeviation

Int

Standard deviation of the weekly or monthly driving duration (in min)

@Keep
data class DKDriverRegularity(
    val periodNumber: Int,
    val tripNumberMean: Int,
    val tripNumberStandardDeviation: Int,
    val distanceMean: Int,
    val distanceStandardDeviation: Int,
    val durationMean: Int,
    val durationStandardDeviation: Int
)

DKDriverDistanceEstimation

DKDriverDistanceEstimation is an object providing distance estimation by week, month or year.

Attribute
Type
Description

weekDistance

Int

Estimated weekly distance (in km)

monthDistance

Int

Estimated monthly distance (in km)

yearDistance

Int

Estimated annual distance (in km)

confidence

Confidence level indicator, based on the available data

@Keep
data class DKDriverDistanceEstimation(
    val weekDistance: Int,
    val monthDistance: Int,
    val yearDistance: Int,
    val confidence: DKDriverDistanceEstimationConfidence
)

DKDriverDistanceEstimationConfidence

DKDriverDistanceEstimationConfidence indicates the distance estimation confidence class.

Value
Description

LOW

If less than 8 weeks since driver’s subscription

MEDIUM

If between 9 and 16 weeks since driver’s subscription

HIGH

If more than 16 weeks since driver’s subscription

@Keep
enum class DKDriverDistanceEstimationConfidence {
    LOW,
    MEDIUM,
    HIGH
}

DKRoadContextInfo

DKRoadContextInfo is an object providing information about road context for the driver.

Attribute
Type
Description

roadContext

Road context

distancePercentage

Double

Percentage of total distance driven in this context

durationPercentage

Double

Percentage of total duration driven in this context

consumedEnergyPercentage

Double

Percentage of total energy driven in this context

@Keep
data class DKRoadContextInfo(
    val roadContext: RoadContext,
    val distancePercentage: Double,
    val durationPercentage: Double,
    val consumedEnergyPercentage: Double
)

DKCommonTripType

DKCommonTripType indicates the type of trip.

Value
Description

MOST_FREQUENT

Most frequent trip

UNKNOWN

Unknown type for the SDK (if a new type is added but the SDK is not up to date)

@Keep
enum class DKCommonTripType {
    MOST_FREQUENT,
    UNKNOWN
}

DKCommonTrip

DKCommonTrip is an object providing information about a trip.

Attribute
Type
Description

type

Type of trip

tripNumber

Int

Number of trips

distanceMean

Int

Average trip distance (in km)

durationMean

Int

Average trip duration (in min)

roadContext

Road context type

@Keep
data class DKCommonTrip(
    val type: DKCommonTripType,
    val tripNumber: Int,
    val distanceMean: Int,
    val durationMean: Int,
    val roadContext: RoadContext
)

DKMobilityAreaType

DKMobilityAreaType indicates the type of mobility area.

Value
Description

PERCENTILE_50TH

The radius including 50% of all the user’s trips

PERCENTILE_90TH

The radius including 90% of all the user’s trips

@Keep
enum class DKMobilityAreaType {
    PERCENTILE_50TH,
    PERCENTILE_90TH
}

Driver alert in case of crash

Principle

The crash detection feature includes an interface that informs the driver that a crash has been detected so he can confirm it to automatically call for help if needed.

Enable crash detection feedback

By default, the crash detection feedback is disabled. When this feature is enabled, the crash detection feedback displays a notification or a screen and calls an emergency number when a crash is confirmed by the driver.

To enable crash detection feedback, the following method needs to be called:

DriveKitTripAnalysisUI.shared.enableCrashFeedback(roadsideAssistanceNumber: String, config: DKCrashFeedbackConfig)

With the following parameters:

Attribute
Type
Description

roadsideAssistanceNumber

String

Emergency number that will be called if there is a crash.

config

DKCrashFeedbackConfig

Configuration of the feedback.

DKCrashFeedbackConfig

Attribute
Type
Description

notification

DKCrashFeedbackNotification

Configuration of the notification.

crashVelocityThreshold

Double

Minimal speed when the crash occurred. For example, if crashVelocityThreshold is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user. Default value : 0.0 km/h

DKCrashFeedbackNotification

Attribute
Type
Description

title

String

Title that appears on the notification.

message

String

Message that appears on the notification

crashAlert

DKCrashAlert

Object that describes how the user will be noticed when a feedback is asked. Default value : SILENCE

DKCrashAlert

Attribute
Description

silence

Device will not vibrate or ring

vibration

Device will vibrate

soundAndVibration

Device will ring and vibrate

Disable Feedback crash detection

To disable crash detection feedback, call the following method:

DriveKitTripAnalysisUI.shared.disableCrashFeedback()

Test your integration with the crash simulator

To simulate a car accident, simply install the trip simulator and start a simulation with the configuration tripWithCrash.

Register to the Crash Notification API

Our platform can share a collision report that contains information about the accident.

This information can be used to:

  • trigger the intervention of an assistance service,

  • and initiate the accident management process.

Advanced configurations

Hiding the delete trip button

The SDK includes a feature that allows the user to manually delete a trip. Depending on your use case, you can allow or prohibit the deletion of a trip.

Therefore, the SDK contains a setting parameter to show or hide the delete button. The delete trip button is displayed as a "trash can" and appears at the top right of the trip detail screen.

By default delete trip button is enabled. To disable it, call the following method with parameter enable set to true:

DriveKitDriverDataUI.shared.enableDeleteTrip(enable: true)

Trip list sorting

The analyzed trips are displayed on a list. This list shows the grouped trips by day from the most recent to the oldest one.

If more than one trip have been completed in a day, the trips for a day can be sorted in ascending or descending order of time.

By default, trips are sorted in ascending order, to change it, call the following method with parameter dayTripDescendingOrder set to true:

DriveKitDriverDataUI.shared.configureDayTripDescendingOrder(dayTripDescendingOrder: true)

Trip advice feedback

If trip advice is configured for your DriveQuant account, drivers will receive trip advice at the end of a trip according to their driving.

For this advice, you can enable a feedback screen that allows your drivers to send a feedback about the relevance of the advice.

By default, this screen is enabled but you can disable it by calling the following method withe parameter enable set to false:

DriveKitDriverDataUI.shared.enableAdviceFeedback(enable: false)

Enable alternative transportation modes display

The DriveKit SDK can detect alternative modes of transport such as public transport. In this case, the driver behaviour is not evaluated since he is not in a driving situation.

The Driver Data component automatically splits the rated trips from those that should not be rated in two separate lists.

  • The main list contains the trips scored and corresponding to transport modes where the user is in a driving situation (car, motorbike or truck).

  • The secondary list displays the trips identified in transportation modes where the user is not in a driving situation.

We have chosen to distinguish these trips and separate them into two independent lists. The list of main trips (i.e. scored) is always displayed by default. The list of alternative trips (i.e. not scored) can be shown or hidden according to your needs. By default, it is not displayed.

When this function is enabled, a filter icon appears in the upper right corner of the trip list screen. By clicking on it, you can select the list of trips made with an alternative mode of transport. To display the list of trips identified as alternative transportation modes, you can use the code below.

DriveKitDriverDataUI.shared.enableAlternativeTrips(true)

My Synthesis

My synthesis screen contains two very interesting insights for the driver:

  • His level against a reference scale that tells him whether he needs to make efforts and progress ;

  • His level in regard to the performance of other drivers belonging to the same organisation as him. The comparison is an interesting lever to motivate the driver to improve his driving.

For each selectable period, the driver will be able to view his average score computed by services that run on the DriveQuant platform.

The user can easily navigate to consult:

  • The evolution of his driving scores by theme compared to the previous active period ;

  • His driving score compared to the community thanks to the minimal, median and max community scores ;

  • How many trips and total distance he made during the selected period.

​​To include the “My Synthesis” screen into your app, call the following method:

DriveKitDriverDataUI.shared.getMySynthesisViewController()

And present the returned view controller using your app’s navigation API.

Configure scores themes to display

You can select which scores you want to display on the screen as well as the scores ordering, by calling the following method:

DriveKitUI.shared.scores = [.safety, .ecoDriving, .distraction, .speeding]

Default and accepted values are:

[.safety, .ecoDriving, .distraction, .speeding]

For .distraction and .speeding scores, make sure that the services are activated on your DriveQuant account or the SDK will filter them out and they will not be displayed in the UI even if you add them here.

Trips widgets

This section introduces graphical elements that simplify the display of driver behaviour scores synthesis.

Driver synthesis scorecard

The Driver Data component includes a component to visualise the average performance of a driver.

The synthesis scorecard shows as main information the averages of each of the driving scores calculated over a 7 days since the last trip date.

The synthesis scorecard also indicates, over this period, the number of trips performed as well as the total distance and driving duration.

The component allows you to select the scores displayed and the order in which they are displayed. To move from one score to another, simply swipe the scorecards.

To include the scorecards into your app, call the following method:

DriveKitDriverDataUI.shared.getLastTripsSynthesisCardsView([.safety, .ecodriving, .distraction, .speeding])

The order in which the scorecards are displayed corresponds to the order of the items in the table. To hide a theme, simply do not add it to the table.

The value .speeding can be set only if this configuration is enabled for your API key.

Last trip widget

The Driver Data component includes a widget to display a short chronological list of the driver's last trips.

With the last trip widget, the driver can get a quick overview of his last 10 trips with a simple swipe.

Each small card corresponds to a trip and the user can access the full details and map view by tapping on the current card.

By selecting the last card, the user can access the list of all the trips.

​​To include the last trip widget into your app, call the following method:

DriveKitDriverDataUI.shared.getLastTripsView(parentViewController: <a_view_controller>)

And embed the returned view into your layout.

Get Started

Pre-requisite

Integration

To add Driver Data UI module to your app, add the following line to your dependencies in your application build.gradle file:

dependencies {
    implementation 'com.drivequant.drivekit:drivekit-driver-data-ui:$drivekitui_version'
}

Replace $drivekitui_version with the DriveKit version you are using in your app

Google API Key

Introduction

A Google API Key is mandatory in order to use Driver Data UI. Without it, the trip detail screen will not work because it draws the desired trip using the Google Maps SDK that requires credentials.

  • a billing account

  • Maps SDK for Android enabled

Create an API Key

Add the API Key

Initialization

Then, to initialize the module in your app, you must call the initialization method in onCreate method of your Application class:

fun initialize()

Override colors and texts

Trip list main theme

It is possible to choose the main theme for the trip list. The main theme of the trip list is used to select the score to be displayed on the left side of the trip list. This setting allows you to choose among one of the 6 themes below:

  • SAFETY: The driving safety score.

  • ECO_DRIVING: The eco-driving score.

  • DISTRACTION: The driving distraction score.

  • DURATION: The trip distance.

  • DISTANCE: The driving duration.

  • SPEEDING: The speeding score.

The value SPEEDING can be set only if this configuration is enabled for your API key.

The main theme can be configured calling the following method:

fun configureTripData(tripData: TripData)

The default value is SAFETY.

Trip map items

A trip is analyzed through several dimensions and DriveQuant's services provide multiple categories of scores. Depending on your need, you can highlight the scores of interest and hide some of them. The configuration of the trip detail screen allows to choose the displayed themes and the displaying order. To switch from one theme to another, simply swipe the bottom part of the screen or click on one of the pictograms in the navigation bar at the top of the screen.

The screens that can be displayed are listed below:

  • The safety analysis results: SAFETY.

  • The eco-driving results: ECO_DRIVING.

  • The distracted driving results: DISTRACTION.

  • The speeding driving results: SPEEDING.

  • A scrollable list that displays all the events that occurred during the trip: INTERACTIVE_MAP.

  • Synthetic data of the trip as average speed, CO2 emissions, estimated fuel consumption, driving conditions: SYNTHESIS.

The value SPEEDING can be set only if this configuration is activated on your team.

Map items can be configured by calling the following method:

fun configureMapItems(mapItems: List<MapItem>)

The default value is:

[SAFETY, ECODRIVING, DISTRACTION, SPEEDING, INTERACTIVE_MAP, SYNTHESIS]

The order in which the screens are displayed corresponds to the order of the items in the table. To hide a theme, simply do not add it to the table.

Display fragment

To show fragment in your activity, you just have to create an instance of TripListFragment with the following method:

DriverDataUI.createTripListFragment()
DriverDataUI.INSTANCE.createTripListFragment();

and then show it using a FragmentManager.

supportFragmentManager.beginTransaction()
    .replace(R.id.container, DriverDataUI.createTripListFragment())
    .commit()
getSupportFragmentManager().beginTransaction()
    .replace(R.id.container, DriverDataUI.INSTANCE?.createTripListFragment())
    .commit();

My Driver Profile

Introduction

My Driver Profile has two main screens:

  1. The first screen displays information on driving habits and the main characteristics that define a driver's profile.

  2. The second screen highlights the driving conditions that the driver has experienced during his trips.

Main screen

The main screen is divided into three parts:

  1. The first describes the different components of the driver profile.

  2. The second one displays the estimated and actual distances per period (week, month and year).

  3. The third one gives the most common driver’s trip in terms of distance and duration.

Driver’s profile cards

Every driver has a signature that depends on how they use their vehicle. The driver profile function gives an accurate overview of the driver's profile based on an analysis of his driving data.

We have divided the driver profile into 5 characteristics that depends on key variables:

  • the annual distance driven per year,

  • the mobility area that includes 90% of the driver’s trips,

  • the percentage of weeks during which the driver has used his vehicle,

  • the regularity based on the relative standard deviations of the weekly distance and trip number,

  • the main driving context.

Distance estimation cards

These cards compare for different periods (week, month and year)the actual distance (ie. recorded) with the estimated distance computed from the driver historical data.

Driver’s usual trip

The purpose of this section is to highlight the driver's most common trip in terms of duration and distance.

A minimum of 2 weeks of activity and 500 km driven is required to display the driver profile data. The accuracy and quality of the results improve with the amount of historical data analysed.

​​To include the “Driver Profile” screen into your app, call the following method:

DriveKitDriverDataUI.shared.getDriverProfileViewController()

And present the returned view controller using your app’s navigation API.

Driving conditions screen

To visualize the exposure to the external conditions, we have embedded a screen in the graphical component DriverData UI representing the distances covered by the driver in these conditions and per period: week, month and year.

The driver can scroll through cards to visualize the conditions that result from the analysis of his trips:

  • the ranges of distances mostly traveled;

  • trips made during the week or on weekends;

  • the types of roads travelled;

  • the weather conditions;

  • day and night trips;

This information helps the driver to be conscious of the inherent risks and is useful to personalize the driving advice.

You can access this screen by clicking on the button “View my driving conditions” in the main screen.

If you want to include the “Driving Conditions” screen into your app as a standalone screen, call the following method:

DriveKitDriverDataUI.shared.getDrivingConditionsViewController()

And present the returned view controller using your app’s navigation API.

My Synthesis

My synthesis screen contains two very interesting insights for the driver:

  • His level against a reference scale that tells him whether he needs to make efforts and progress ;

  • His level in regard to the performance of other drivers belonging to the same organisation as him. The comparison is an interesting lever to motivate the driver to improve his driving.

For each selectable period, the driver will be able to view his average score computed by services that run on the DriveQuant platform.

The user can easily navigate to consult:

  • The evolution of his driving scores by theme compared to the previous active period ;

  • His driving score compared to the community thanks to the minimal, median and max community scores ;

  • How many trips and total distance he made during the selected period.

​​To display the “My Synthesis” screen into your app, call the following method:

Configure scores themes to display

You can select which scores you want to display on the screen as well as the scores ordering, by calling the following method:

Default and accepted values are:

For DISTRACTION and SPEEDING scores, make sure that the services are activated on your DriveQuant account or the SDK will filter them out and they will not be displayed in the UI even if you add them here.

Trips widgets

This section introduces graphical elements that simplify the display of driver behaviour scores synthesis.

Driver synthesis scorecard

The Driver Data component includes a component to visualise the average performance of a driver.

The synthesis scorecard shows as main information the averages of each of the driving scores calculated over a 7 days since the last trip date.

The synthesis scorecard also indicates, over this period, the number of trips performed as well as the total distance and driving duration.

The component allows you to select the scores displayed and the order in which they are displayed. To move from one score to another, simply swipe the scorecards.

To include the scorecards into your app, call the following method:

The order in which the scorecards are displayed corresponds to the order of the items in the table. To hide a theme, simply do not add it to the table.

The value SPEEDING can be set only if this configuration is enabled for your API key.

Last trip widget

The Driver Data component includes a widget to display a short chronological list of the driver's last trips.

With the last trip widget, the driver can get a quick overview of his last 10 trips with a simple swipe.

Each small card corresponds to a trip and the user can access the full details and map view by tapping on the current card.

By selecting the last card, the user can access the list of all the trips.

​​To include the last trip widget into your app, call the following method:

And embed the returned view into your layout.

Advanced configurations

Hiding the delete trip button

The SDK includes a feature that allows the user to manually delete a trip. Depending on your use case, you can allow or prohibit the deletion of a trip.

Therefore, the SDK contains a setting parameter to show or hide the delete button. The delete trip button is displayed as a "trash can" and appears at the top right of the trip detail screen.

By default delete trip button is enabled. To disable it, call the following method with parameter enableDeleteTrip set to false:

Trip list sorting

The analyzed trips are displayed on a list. This list shows the grouped trips by day from the most recent to the oldest one.

If more than one trip have been completed in a day, the trips for a day can be sorted in ascending or descending order of time.

By default, trips are sorted in ascending order, to change it, call the following method with parameter dayTripDescendingOrder set to true:

Trip advice feedback

If trip advice is configured for your DriveQuant account, drivers will receive trip advice at the end of a trip according to their driving.

For this advice, you can enable a feedback screen that allows yours drivers to send a feedback about the relevance of the advice.

By default, this screen is enabled but you can disable it by calling the following method with parameter enable set to false:

Enable alternative transportation modes display

The DriveKit SDK can detect alternative modes of transport such as public transport. In this case, the driver behaviour is not evaluated since he is not in a driving situation.

The Driver Data component automatically splits the rated trips from those that should not be rated in two separate lists.

  • The main list contains the trips scored and corresponding to transport modes where the user is in a driving situation (car, motorbike or truck).

  • The secondary list displays the trips identified in transportation modes where the user is not in a driving situation.

We have chosen to distinguish these trips and separate them into two independent lists. The list of main trips (i.e. scored) is always displayed by default. The list of alternative trips (i.e. not scored) can be shown or hidden according to your needs. By default, it is not displayed.

When this function is enabled, a filter icon appears in the upper right corner of the trip list screen. By clicking on it, you can select the list of trips made with an alternative mode of transport. To display the list of trips identified as alternative transportation modes, you can use the code below.

Location sharing

Location sharing while driving provides peace of mind to family members. The graphical interface helps the user to enable location sharing and create a link that displays his location on a map to a friend or family member while driving.

The feature is implemented across three distinct screens:

  1. Introduction Screen: The feature is disabled by default. The first screen explains the location-sharing principle.

  2. Duration Selection Screen: On the second screen, the user can choose the duration for sharing his trip location. The available options include one day, one week, or one month.

  3. Active Sharing Screen: The last screen confirms that location sharing is active. It includes a button that allows the user to generate and share a link displaying his real-time location. Additionally, it displays the remaining time before the link expires.

To integrate and display this feature within your application, invoke the following method:

after calling the DriveKit SDK's method.

DKTripRecordingStartedState object is described .

Called each time a trip is confirmed. DKTripRecordingConfirmedState object is described .

DKTripRecordingCanceledState object is described .

Called when trip recording has ended, before sending trip data to DriveQuant's servers. DKTripRecordingFinishedState object is described .

object contains the trip analysis result made on DriveQuant's server.

Called when a trip is started and confirmed, for each location point recorded by the SDK. Data available in TripPoint object are described .

This method is called every time the state of the SDK changed with the new state as parameter. States are described .

Called when a crash event is detected. Triggered if crash detection is enabled. Read more

Called when crash feedback is enabled and a confirmed crash is detected. Triggered if Crash Detection is enabled. Read more

tripStarted(startMode: StartMode) This method has been deprecated to be replaced by: tripRecordingConfirmed(state: DKTripRecordingConfirmedState)

Possible values are described .

tripCancelled(cancelTrip: CancelTrip) This method has been deprecated to be replaced by: tripRecordingCanceled(state: DKTripRecordingCanceledState)

This method is called when a trip is cancelled. CancelTrip indicates which event cancels the trip. Possible values are described .

This method has been deprecated to be replaced by: tripFinished(result: TripResult)

Detailed description of these data are available .

This method is deprecated and will be removed in a future version. It is replaced by the DKDeviceConfigurationListener. Read more .

Before starting DriveKit Driver Data integration, make sure that you have .

If you have , an initialization phase is required to use the functions offered by the Driver Data component. To initialize Driver Data component in your app, you must call the initialization method in onCreate method of your application class.

To get , you have to call the following method:

The second argument of the onResponse method is a list of objects.

To get a specific , you have to call the following method:

TripSyncStatus can have the same value as and the value FAILED_TO_SYNC_SAFETY_EVENTS if the safety events synchronization failed.

The second argument of the onResponse method is the requested object, if exists.

If set to true, the returned timeline data will not contain items ( and ) where there are only unscored trips.

The second argument in the callback is a list of object, one per requested period.

The second argument in the callback is the object requested.

Before starting DriveKit Driver Data UI integration, make sure that you have and components, especially if you have .

On this , you also have a demo app and source code of Driver Data UI that you can use as an example.

If you have , the Driver Data UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitDriverDataUI:

To override colors and texts in Driver Data UI SDK, see .

[]

[: []]

?

?

?

?

?

[: Int]

[: Double]

[: Int]

[: Double]

?

?

t

Map<, >

Map<, >

Map<, Int>

You can find more details on the and documentation.

List<>

Map<, List<>>

?

?

?

?

?

Map<, Int>

Map<, Double>

Map<, Int>

Map<, Double>

?

?

Map<, >

Map<, >

Map<, Int>

In order to check your integration and test the crash detection feature, you can use the trip simulator described in section

If you want to know more and if you need to collect crash data on your platform, we invite you to contact us by email at

Before starting DriveKit Driver Data UI integration, make sure that you have and components, especially if you have .

On a , you have a demo app and source code of Driver Data UI that you can use as an example.

According to the , please check that you already have:

If you already have a Google API Key that can be used for Maps SDK, directly go to the section

Please follow the official documentation to create your own Google API Key.

Please follow the official documentation to add the API Key to your application project.

If you have , the Driver Data UI module must also be manually initialized.

To override colors and texts in Driver Data UI SDK, see

⚠️
⚠️
⚠️
here
here
here
initialized DriveKit
DKDriverTimeline
Github repository
Common UI configuration
iOS
Android
contact@drivequant.com
Github repository
official documentation
Adding the API Key to your app
here
here
Common UI configuration.
startTrip()
here
here
here
here
here
TripResult
here
here
Driver trips
Trip
trip
Trip
here
here
disabled the SDK auto-initialization
initialized DriverData
Common UI
disabled the SDK auto-initialization
disabled the SDK auto-initialization
above
DKDriverProfile
initialized DriverData
Common UI
disabled the SDK auto-initialization
disabled the SDK auto-initialization
simulate a crash during a trip.
DriveKitNavigationController.driverDataUIEntryPoint?.startMySynthesisActivity(context)
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startMySynthesisActivity(context);
var scores: List<DKScoreType> = DKScoreType.values().toList()
[SAFETY, ECO_DRIVING, DISTRACTION, SPEEDING]
fun getLastTripsSynthesisCardsView(
    synthesisCards: List<LastTripsSynthesisCard> = listOf(
        LastTripsSynthesisCard.SAFETY,
        LastTripsSynthesisCard.DISTRACTION,
        LastTripsSynthesisCard.ECO_DRIVING,
        LastTripsSynthesisCard.SPEEDING
    ), listener: SynthesisCardsViewListener
)
fun getLastTripsView(
    headerDay: HeaderDay = HeaderDay.DISTANCE,
    lastTripMaxNumber: Int = 10
): Fragment {
fun enableDeleteTrip(enableDeleteTrip: Boolean)
fun dayTripDescendingOrder(dayTripDescendingOrder: Boolean)
fun enableAdviceFeedback(enableAdviceFeedback: Boolean)
fun enableAlternativeTrips(enableAlternativeTrips: Boolean)
DriveKitTripAnalysisUI.startTripSharingActivity(context)
DriveKitTripAnalysisUI.INSTANCE.startTripSharingActivity(context);
DKAllContextItem
DKRoadContextItem
DKPeriod
DKAllContextItem
RoadContext
DKRoadContextItem
DKSafety
DKEcoDriving
DKDistraction
DKSpeeding
DKDrivingConditions
DKDrivingCategory
DKDrivingCategory
RoadContext
DKSafety
DKEcoDriving
DKDistanceProfile
DKActivityProfile
DKRegularityProfile
RoadContext
DKMobilityProfile
DKDriverStatistics
DKDriverRegularity
DKDriverRegularity
DKDriverDistanceEstimation
RoadContext
DKRoadContextInfo
DKCommonTripType
DKCommonTrip
DKMobilityAreaType
DKDriverDistanceEstimationConfidence
RoadContext
DKCommonTripType
RoadContext
DKPeriod
DKAllContextItem
DKRoadContext
DKRoadContextItem
DKSafety
DKEcoDriving
DKDistraction
DKSpeeding
DKDrivingConditions
DKDrivingCategory
DKDrivingCategory
DKRoadContext
DKSafety
DKEcoDriving
DKDistanceProfile
DKActivityProfile
DKRegularityProfile
DKRoadContex
DKMobilityProfile
DKDriverStatistics
DKDriverRegularity
DKDriverRegularity
DKDriverDistanceEstimation
DKRoadContext
DKRoadContextInfo
DKCommonTripType
DKCommonTrip
DKMobilityAreaType
DKDriverDistanceEstimationConfidence
DKRoadContext
DKCommonTripType
DKRoadContext
DKWeather
DKWeather
DKWeather
DKWeather
ranking
badges
ranking
badges

My Driver Profile

Introduction

My Driver Profile has two main screens

  1. The first screen displays information on driving habits and the main characteristics that define a driver's profile.

  2. The second screen highlights the driving conditions that the driver has experienced during his trips.

Main screen

The main screen is divided into three parts:

  1. The first describes the different components of the driver profile.

  2. The second one displays the estimated and actual distances per period (week, month and year).

  3. The third one gives the most common driver’s trip in terms of distance and duration.

Driver’s profile cards

Every driver has a signature that depends on how they use their vehicle. The driver profile function gives an accurate overview of the driver's profile based on an analysis of his driving data.

We have divided the driver profile into 5 characteristics that depends on key variables:

  • the annual distance driven per year

  • the mobility area that includes 90% of the driver’s trips,

  • the percentage of weeks during which the driver has used his vehicle,.,

  • the regularity based on the relative standard deviations of the weekly distance and trip number.

  • the main driving context.

Distance estimation cards

These cards compare for different periods (week, month and year)the actual distance (ie. recorded) with the estimated distance computed from the driver historical data.

Driver’s usual trip

The purpose of this section is to highlight the driver's most common trip in terms of duration and distance.

A minimum of 2 weeks of activity and 500 km driven is required to display the driver profile data. The accuracy and quality of the results improve with the amount of historical data analysed.

​​To include the “Driver Profile” screen into your app, call the following method:

DriveKitNavigationController.driverDataUIEntryPoint?.startDriverProfileActivity(context)
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startDriverProfileActivity(context);

And present the returned view controller using your app’s navigation API.

Driving conditions screen

To visualize the exposure to the external conditions, we have embedded a screen in the graphical component DriverData UI representing the distances covered by the driver in these conditions and per period: week, month and year.

The driver can scroll through cards to visualize the conditions that result from the analysis of his trips:

  • the ranges of distances mostly traveled;

  • trips made during the week or on weekends;

  • the types of roads travelled;

  • the weather conditions;

  • day and night trips;

This information helps the driver to be conscious of the inherent risks and is useful to personalize the driving advice.

You can access this screen by clicking on the button “View my driving conditions” in the main screen.

If you want to include the “Driving Conditions” screen into your app as a standalone screen, call the following method:

DriveKitNavigationController.driverDataUIEntryPoint?.startDrivingConditionsActivity(context)
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startDrivingConditionsActivity(context);

And present the returned view controller using your app’s navigation API.

Introduction

The DriveKit Vehicle module allows you to select one or more vehicles and to choose the automatic start mode of each vehicle.

The selection of the vehicle is an important step since the driving indicators computed by the application are based on the vehicle characteristics (mass, dimension and powertrain).

There are two types of vehicles that can be added: cars or trucks.

Each declared vehicle is linked to the driver's account.

A start mode can be defined for each vehicle.

Depending on your use case, you can select the type of automatic start mode:

  • The natural (GPS) mode which relies on the phone sensors.

  • The Beacon mode which uses a small iBeacon tag.

  • The Bluetooth mode, which uses a Bluetooth device previously paired to the driver's phone.

DriveKit includes a simple and configurable interface to set up screens in your application from which the driver can configure his vehicle and choose the appropriate start mode.

The advantage of DriveKit is that this information is stored in a local database and synchronised with a remote database.

Get started

Prerequisite

Integration

To add Timeline UI module to your app, add the following line to your dependencies in your application build.gradle file:

dependencies {
    implementation 'com.drivequant.drivekit:drivekit-timeline-ui:$drivekitui_version'
}

Replace $drivekitui_version with the DriveKit version you are using in your app

Initialization

Then, to initialize the module in your app, you must call the initialization method in onCreate method of your Application class:

fun initialize()

Configure main screen scores

You can select which scores you want to display on the main screen as well as the scores ordering, by calling the following method:

DriveKitUI.scores = listOf(
   DKScoreType.SAFETY,
   DKScoreType.ECO_DRIVING,
   DKScoreType.DISTRACTION,
   DKScoreType.SPEEDING
)
DriveKitUI.INSTANCE.setScores(Arrays.asList(
       DKScoreType.SAFETY,
       DKScoreType.ECO_DRIVING,
       DKScoreType.DISTRACTION,
       DKScoreType.SPEEDING)
);

Default and accepted values:

[ SAFETY, ECO_DRIVING, DISTRACTION, SPEEDING ]

For DISTRACTION and SPEEDING scores, make sure that the services are activated on your DriveQuant account or the SDK will filter them out and they will not be displayed in the UI even if you add them here.

Get started

Prerequisite

Integration

The Timeline UI module is available on Cocoapods master repo.

To access the framework in the repository, add the following lines to your Podfile:

target 'my-target' do
pod 'DriveKitDriverDataTimelineUI'

end

Then, run pod install.

Initialization

import DriveKitDriverDataTimelineUI

Then, to initialize Timeline UI module in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate:

import DriveKitCore
import DriveKitCommonUI
import DriveKitDriverDataTimelineUI
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  DriveKit.shared.initialize()
  DriveKitUI.shared.initialize()
  DriveKitDriverData.shared.initialize()
  DriveKitDriverDataTimelineUI.shared.initialize()
  //...
}

Configure main screen scores

You can select which scores you want to display on the main screen as well as the scores ordering, by calling the following method:

DriveKitUI.shared.scores = [.safety, .ecoDriving, .distraction, .speeding]

Default and accepted values:

[ .safety, .ecoDriving, .distraction, .speeding ]

For .distraction and .speeding scores, make sure that the services are activated on your DriveQuant account or the SDK will filter them out and they will not be displayed in the UI even if you add them here.

We recommend you to test this component in the before you integrate it in your application.

Before starting DriveKit Timeline UI integration, make sure that you have initialized and modules.

On, you can also find a demo application that contains the DriveKit Timeline component. This code is open source and you can use it as an example.

If you have , the Timeline UI module must also be manually initialized.

Before starting DriveKit Timeline UI integration, make sure that you have initialized and modules.

On, you can also find a demo application that contains the DriveKit timeline component. This code is open source and you can use it as an example.

If you have , the Timeline UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitDriverDataTimelineUI:

Driver Data
Common UI
this Github repository
Driver Data
Common UI
this Github repository
DriveKit Demo App
disabled the SDK auto-initialization
disabled the SDK auto-initialization
Automatic trip analysis lifecycle
Simplified representation of the DriveKit architecture
Working hours screen
Feedback crash graphical interface
The trip recording widget when no trip is in progress (left) and when a trip is analysed (right)
Options proposed to the user when a trip is being recorded
Layout of the diagnosis screen on iOS
Log scale sensitivity function for speeding score
Speed score sensitivity function in decimal scale
Onboarding screens
Diagnostic screens
Layout of the diagnosis screen on Android
Trip map items
Trip list and trip detail screens provided into the Driver Data SDK graphics library
Trip details screens
Trips widgets
My synthesis screen
My Driver Profile screens
Eco-driving advice
Alternative transportation mode list
My synthesis screen
Trip map items
My Driver Profile 2 screens
Driver's profile cards
Distance estimation cards
Driver's usual trip
Driving conditions screen
Eco-driving advice
Alternative transportation mode list
My Driver Profile 2 screens
Driver's profile cards
Distance estimation cards
Driver's usual trip
Driving conditions screen

Introduction

The timeline component displays the user's driving score history to help them understand if they are making progress.

The data represents weekly or monthly averages that are calculated periodically by services that run on the DriveQuant platform and automatically synchronised with the DriveKit SDK.

The design is designed to be technical but ergonomic in order to highlight the qualities and weaknesses of the user's driving behaviour.

The user can easily navigate to consult :

  • the evolution of his driving scores by theme. The safety score out of 10 for example.

  • the evolution of sub-scores or secondary driving indicators that were used to build the main driving scores. The number of hard braking for example.

Main screen

The main screen highlights the scores for each theme. The driver can choose between two types of display:

  1. weekly average history

  2. monthly average history

Score detail screen

The secondary screens are accessible from the main screen by tapping on "See more details about my score".

They contain the sub-scores of the selected theme. As for the main screens, data is available by week and month.

🛡Safety sub-scores :

  • Number of accelerations per 100 km

  • number of brakings per 100 km

  • Adherence limits per 100 km

🌿 Eco-driving sub-scores:

  • Acceleration score

  • Deceleration score

  • Speed maintain score

  • Fuel consumption (in l)

  • Achievable fuel savings (in l)

  • CO2 mass (in kg)

📱Distraction sub-scores:

  • Number of phone unlocks per 100 km

  • Duration of forbidden calls per 100 km

  • Percentage of trips with forbidden calls

🏎 Speeding sub-scores:

  • Overspeeding relative duration

  • Overspeeding relative distance

Timeline UI - main screen
Timeline UI - Score detail screen