# 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.

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 [iOS](https://github.com/DriveQuantPublic/drivekit-ui-ios?tab=readme-ov-file#how-to-use-the-demo-application) and [Android](https://github.com/DriveQuantPublic/drivekit-ui-android?tab=readme-ov-file#how-to-use-the-demo-application)).

## **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.

![Simplified representation of the DriveKit architecture](/files/-LoB-fg0YdAxARxEaClG)

## **What are the main features included in the mobile SDK?**

The DriveKit SDK is a set of independent features integrated into modules.&#x20;

Some of these modules include graphical libraries with user interfaces.&#x20;

The table below summarizes all the modules included in DriveKit:

<table><thead><tr><th width="197">Module</th><th width="422">Description</th><th align="center">UI</th></tr></thead><tbody><tr><td><strong>Core</strong></td><td>SDK management: authentication, user creation, diagnostic functions (logs, permissions and sensors status).</td><td align="center">❌</td></tr><tr><td><a href="/pages/-LmxzDIkA6-fw16hN67U"><strong>Trip Analysis</strong></a></td><td>Recording of sensor signals and automatic trip detection.</td><td align="center">✅</td></tr><tr><td><a href="/pages/-Lrx7KSKYt7QayVH_Qur"><strong>Driver Data</strong></a></td><td>Synchronisation of all user data in the local SDK database.</td><td align="center">✅</td></tr><tr><td><a href="/pages/-M35uIPPHqIbkN_RoBWS"><strong>Vehicle</strong></a></td><td>Configuration of one or more vehicles linked to a user's account.</td><td align="center">✅</td></tr><tr><td><a href="/pages/-M6KSnU0VBVEBn5N8kgQ"><strong>Permissions Utils</strong></a></td><td>Graphical interfaces that help to collect the user permissions to run the SDK.</td><td align="center">✅</td></tr><tr><td><a href="/pages/-MbRlN7qukayKG3Gh4Xr"><strong>Challenge</strong></a></td><td>Management of driving challenges.</td><td align="center">✅</td></tr><tr><td><a href="/pages/-M1oaqq9KD81iVChFD7W"><strong>Driver Achievement</strong></a></td><td>User engagement features: ranking, badge and streaks</td><td align="center">✅</td></tr></tbody></table>

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**

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 [iOS](https://github.com/DriveQuantPublic/drivekit-ui-ios) and [Android](https://github.com/DriveQuantPublic/drivekit-ui-android).

{% hint style="info" %}
The DriveKit Demo App needs credential. Please, contact us to get your **API key** via: <contact@drivequant.com>&#x20;
{% endhint %}

![](/files/sDvpZ4t1vwdegmQw7SxO)

## **Contact us**

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


# 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

{% content-ref url="/pages/-LXYRCN7xU5dZiTArWme" %}
[iOS](/get-started-drivekit/ios)
{% endcontent-ref %}

## Android guides

Get started for Kotlin and Java

{% content-ref url="/pages/-LXYR72rEyViKN3injkm" %}
[Android](/get-started-drivekit/android)
{% endcontent-ref %}

## 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.


# Trip recording lifecycle

{% hint style="danger" %}
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.
{% endhint %}

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.&#x20;

You can find all resources on [Github](https://github.com/DriveQuantPublic).&#x20;

* Android DriveKit Demo App can be found [here](https://github.com/DriveQuantPublic/drivekit-ui-android/tree/master/app).&#x20;
* iOS DriveKit Demo App can be found [here](https://github.com/DriveQuantPublic/drivekit-ui-ios/tree/master/DriveKitApp).&#x20;

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

The DriveKit SDK ([TRIP ANALYSIS](/trip-analysis/introduction) component) has the ability to automatically detect and record a trip when your application runs in background.

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.

<figure><img src="/files/vLnqiT28S0sFzEOqws0O" alt=""><figcaption><p>Automatic trip analysis lifecycle</p></figcaption></figure>

**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.<br>

## 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.


# 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.


# 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+
* A DriveKit API key. If you don't have an API key, please contact [us](mailto:contact@drivequant.com).

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

{% hint style="info" %}
You can also clone the following [repository with Swift Package Manager](https://github.com/DriveQuantPublic/drivekit-quickstart-spm-ios), configure the required credentials and then simply run the quickstart app!
{% endhint %}

## Set up your project

The DriveKit iOS SDK is available on Swift Package Manager (SPM).

CocoaPods is no longer supported DriveKit UI components since version 3.0.0, as [CocoaPods Trunk is expected to become read-only](https://blog.cocoapods.org/CocoaPods-Specs-Repo/). Remaining modules will also stop supporting CocoaPods as soon as react-native will stop depending on it.

We strongly recommend migrating from CocoaPods to Swift Package Manager (SPM) as soon as possible.

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

{% hint style="warning" %}
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 [Advanced configurations](/get-started-drivekit/ios/advanced-configurations) part.
{% endhint %}

### Swift Package Manager

#### Via Xcode:

* In Xcode, add the DriveKit SDK by navigating to File > Add Package Dependencies...
* In the prompt that appears, enter the DriveKit repository:\
  `https://github.com/DriveQuantPublic/drivekit-sdk-spm.git`&#x20;
* Include DriveKitTripAnalysis in your app.

#### Via Package.swift:

* To integrate DriveKit to a Swift package via a Package.swift file, you can add DriveKit to the dependencies array of your package. For more details, see the [Swift Package Manager documentation](https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html#package-dependency).

```swift
dependencies: [
  .package(name: "DriveKit",
           url: "https://github.com/DriveQuantPublic/drivekit-sdk-spm.git",
           from: "2.0.0"),
  // ...
],
```

* Then in any target that depends on a DriveKit module, add it to the dependencies array of that target:

```swift
.target(
  name: "MyTarget",
  dependencies: [
    .product(name: "DriveKitTripAnalysis", package: "DriveKit"),
    // ...
  ]
),
```

## Configure Capabilities

* Go to the **Capabilities** tab of your target settings.
* Turn on **Background Modes**&#x20;
* Enable **Location updates** (to be able to receive location updates in the background)
* Enable **Background fetch** (to periodically check for changes related to the status of authorizations, sensors, as well as user disconnection. See more info [here](/get-started-drivekit/android/advanced-configurations#listen-for-permissions-and-sensors-status-changes))

<figure><img src="/files/M9Ns4YSKCDoVWqLXkVGb" alt=""><figcaption></figcaption></figure>

## Configure permissions

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

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:

{% tabs %}
{% tab title="Info.plist" %}

```xml
<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>
```

{% endtab %}
{% endtabs %}

<figure><img src="/files/t63OyUBrHA4eXbAWqjhl" alt=""><figcaption></figcaption></figure>

These values can be localized (see our [English file](https://github.com/DriveQuantPublic/drivekit-ui-ios/blob/master/DriveKitApp/Localizable/en.lproj/InfoPlist.strings) for example).

## Configure background task ID

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 [background fetch capability](#configure-capabilities) and a background task id declared in your `Info.plist` file.\
You must add the following line in `Info.plist` file:

{% tabs %}
{% tab title="Info.plist" %}

```xml
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
	<string>com.drivequant.diagnosis.app.refresh</string>
</array>
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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:

<pre class="language-swift"><code class="lang-swift">DKSDKDiagnosis.shared.enqueueDiagnosisOperation(source: .backgroundFetch) { success in
    //task.setTaskCompleted(success: success)
<strong>}
</strong></code></pre>

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

## 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:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func setApiKey(key: String)
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func setUserId(userId: String)
```

{% endtab %}
{% endtabs %}

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.

{% hint style="warning" %}
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 ([GUID](https://www.guidgenerator.com/online-guid-generator.aspx)) for each of your users.
{% endhint %}

{% hint style="danger" %}
DriveKit SDK will not work until you set the API key and the userId.
{% endhint %}

## 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`:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func activateAutoStart(enable: Bool)
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="Podfile" %}

```swift
target 'DriveKit Quickstart' do
   pod 'DriveKitTripAnalysis'
   pod 'DriveKitPermissionsUtilsUI'
end

```

{% endtab %}
{% endtabs %}

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:

```swift
DriveKitPermissionsUtilsUI.shared.showPermissionViews([.location, .activity], parentViewController: self) {
    // Code called when requested permissions are properly 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:

* Configure the [Core](/get-started-drivekit/ios/advanced-configurations) and [TripAnalysis](/trip-analysis/ios) modules with advanced settings. For example, [alert the user once a trip has been analyzed by the DriveQuant servers by displaying a notification](/trip-analysis/ios/triplistener), activate the [crash detection](/trip-analysis/ios/crash-detection), 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 [Driver Data](/driver-data/introduction) module.
* Associate each trip to a vehicle that you can configure with the [Vehicle](/vehicle/introduction) module.
* Improve user retention by organizing [challenges](/challenge/introduction), display [ranking](/driver-achievement/ios/get-started#get-ranking) with the community, show which [badges](/driver-achievement/ios/get-started#get-badges) the driver earned, etc.


# 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.&#x20;

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:

{% tabs %}
{% tab title="Info.plist" %}

```xml
<key>DKAutoInitEnabled</key>
<false/>
```

{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="AppDelegate" %}

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

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
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.
{% endhint %}

## Check your configuration

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

{% tabs %}
{% tab title="DriveKit" %}

```swift
func isConfigured() -> Bool
```

{% endtab %}
{% endtabs %}

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:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func isUserConnected() -> Bool
```

{% endtab %}
{% endtabs %}

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.

{% hint style="info" %}
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.

You can also make files of your application (including DriveKit log files) available in the [iOS Files app](https://support.apple.com/en-us/HT206481) by adding these 2 keys to your project's `Info.plist` file: `UIFileSharingEnabled` and `LSSupportsOpeningDocumentsInPlace,` setting them both to `true.`
{% endhint %}

{% hint style="info" %}
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`.
{% endhint %}

Disable logging by calling the following method:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func disableLogging(showInConsole: Bool = true)
```

{% endtab %}
{% endtabs %}

To activate logging, call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func enableLogging(showInConsole: Bool = true)
```

{% endtab %}
{% endtabs %}

The DriveKit log ZIP file includes a configuration file in JSON format.&#x20;

This file lists the values of all configuration parameters for the DriveKit SDK installed in your user's app.

This [document](https://docs.google.com/spreadsheets/d/1cdU7jM3gLEyFBWpaHf5OH9SSRZkm38YACrohn0Cr-t4/edit?usp=sharing) provides a detailed overview of all the configuration entries included in the config file, along with their definitions and expected values.<br>

## 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.&#x20;

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.

{% hint style="info" %}
Event changes callbacks may not be fired in real time due to technical restrictions of iOS.
{% endhint %}

### DKDeviceConfigurationDelegate

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

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

### Add a delegate

To add a delegate and listen for [Device Configuration Events](#dkdeviceconfigurationevent), you can call the following function:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func addDeviceConfigurationDelegate(_ delegate: DKDeviceConfigurationDelegate)
```

{% endtab %}
{% endtabs %}

### Remove a delegate

&#x20;To remove a specific delegate, call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func removeDeviceConfigurationDelegate(_ delegate: DKDeviceConfigurationDelegate)
```

{% endtab %}
{% endtabs %}

### Remove all delegates

&#x20;To remove all delegates, call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func removeAllDeviceConfigurationDelegates()
```

{% endtab %}
{% endtabs %}

### DKDeviceConfigurationEvent

`DKDeviceConfigurationEvent` is a class describing a device configuration event.

```swift
class DKDeviceConfigurationEvent {
    let type: DKDeviceConfigurationEventType
    let isValid: Bool
}
```

<table><thead><tr><th width="153">Attribute</th><th width="95.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td>Enum</td><td><a href="#dkdeviceconfigurationeventtype"><code>DKDeviceConfigurationEventType</code></a> enum describing the type of event</td></tr><tr><td>isValid</td><td>Boolean</td><td>Boolean describing whether the device configuration event is valid or not</td></tr></tbody></table>

### DKDeviceConfigurationEventType

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

Possible types are:

<table><thead><tr><th width="284">Event type</th><th>Description</th></tr></thead><tbody><tr><td><code>activityPermission</code></td><td>Motion &#x26; Fitness permission status changed</td></tr><tr><td><code>locationPermission</code></td><td>Location permission status changed</td></tr><tr><td><code>bluetoothPermission</code></td><td>Bluetooth permission status changed</td></tr><tr><td><code>notificationPermission</code></td><td>Notifications permission status changed</td></tr><tr><td><code>lowPowerMode</code></td><td>Low Power Mode status changed</td></tr><tr><td><code>locationSensor</code></td><td>Location sensor status changed</td></tr><tr><td><code>bluetoothSensor</code></td><td>Bluetooth sensor status changed</td></tr></tbody></table>

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.

<table><thead><tr><th width="288.3333333333333">Event</th><th width="106" align="center">Criticality</th><th>Consequence if value is false</th></tr></thead><tbody><tr><td><code>LocationPermission</code></td><td align="center">🔴</td><td>No trip recording if app has no access to GPS sensor</td></tr><tr><td><code>BluetoothPermission</code></td><td align="center">🟡</td><td>No trip detection based on Bluetooth system</td></tr><tr><td><code>ActivityPermission</code></td><td align="center">🟡</td><td>Detected transportation mode mode can be inaccurate when no access to this permission</td></tr><tr><td><code>NotificationPermission</code></td><td align="center">🟢</td><td>Your application cannot send notification to the user if the permission is revoked.</td></tr><tr><td><code>lowPowerMode</code></td><td align="center">🟢</td><td>No considerable impact</td></tr><tr><td><code>LocationSensor</code></td><td align="center">🔴</td><td>No trip recording if GPS sensor is disabled</td></tr><tr><td><code>BluetoothSensor</code></td><td align="center">🟡</td><td>No trip detection based on Bluetooth system.<br>Can also impact beacon trip detection.</td></tr></tbody></table>

## 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:

```swift
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:

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

Or to update all information:

```swift
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:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func updateUserId(userId: String)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To be able to check whenever `userId` got updated and catch the update status, you have to use [`DriveKitDelegate`](/get-started-drivekit/ios/references#drivekitdelegate) delegate.
{% endhint %}

## Account deletion

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

&#x20;The deletion can be done instantly or with delay.&#x20;

* In the first case, when the method is called, the account is instantly deleted.&#x20;
* 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:

{% tabs %}
{% tab title="DriveKit" %}

```swift
func deleteAccount(instantDeletion: Bool = false)
```

{% endtab %}
{% endtabs %}

`instantDeletion` can have 2 values:&#x20;

* `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.

{% hint style="info" %}
Your team needs to have the deletion feature activated to use this method. Please contact DriveQuant if you need it.
{% endhint %}

{% hint style="info" %}
To be able to check whenever the account deletion is complete, you have to use the [DriveKitDelegate](https://docs.drivequant.com/get-started-drivekit/ios/references#drivekitdelegate) interface.
{% endhint %}

{% hint style="warning" %}
You should restore the DriveKit API key in the `onAccountDeleted()` callback only when the status value is `SUCCESS`.
{% endhint %}

## 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:&#x20;

* 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.

{% hint style="info" %}
The installationId uses the UUID format. Example: `123e4567-e89b-12d3-a456-426614174000`
{% endhint %}

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

{% tabs %}
{% tab title="DriveKit" %}

```swift
var installationId: String?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The returned installationId will be `nil` as long as the user is not authenticated to DriveKit.

For example, you can retrieve the identifier after the `driveKitDidConnect()` callback is triggered. (Read more about the [DriveKitDelegate](/get-started-drivekit/ios/references#drivekitdelegate))
{% endhint %}

## Reset

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

```swift
DriveKit.shared.reset()
```

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


# References

## DriveKitDelegate <a href="#drivekitdelegate" id="drivekitdelegate"></a>

`DriveKitDelegate` is a protocol that can be passed as a parameter during the [DriveKit Core module initialization](/get-started-drivekit/ios#drivekit-initialization). It gives useful events about the user lifecycle.

```swift
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)
}
```

| Method                                                                              | Description                                                                             |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `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. |

## UpdateUserIdStatus

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

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

| Value            | Description                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------ |
| `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                                                |

## RequestError <a href="#deviceconfigevent" id="deviceconfigevent"></a>

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

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

| Value             | Description                                                                                                          |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| `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.                      |

## DeleteAccountStatus

`DeleteAccountStatus` is an enum that describes the deletion status. It can have 3 values:&#x20;

* `success`: Account deleted successfully&#x20;
* `failedToDelete`: Account not deleted, an error has occurred&#x20;
* `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`

## DKPeriod

`DKPeriod` indicates the aggregation size of each timeline object. It is an enum with the following values:

<table><thead><tr><th width="247">Value</th><th>Description</th></tr></thead><tbody><tr><td>week</td><td>Timeline data is aggregated week by week</td></tr><tr><td>month</td><td>Timeline data is aggregated month by month</td></tr><tr><td>year</td><td>Timeline data is aggregated year by year</td></tr></tbody></table>

## 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                  |


# DriveKit 3.0 migration guide

Migration guide for DriveKit 3.0 on iOS platform

## What's changed in v3.0?

### Introduction

Version 3.0 of the DriveKit SDK contains breaking changes: all methods that were marked as deprecated during the past year have been permanently removed.

This guide lists every removed element alongside its recommended replacement, organized by module.&#x20;

Following these steps will keep your integration stable and future-proof.

{% hint style="info" %}
This version also features a newly available callback to retrieve the beacon detected and confirmed during trip recording which will not be presented in this migration guide.
{% endhint %}

### How to use this guide

Each section maps to an SDK module. For every removed element, you'll find:

* The exact method, class, or property that was removed
* The recommended drop-in replacement to use instead

## Module-level reset() methods

The `reset()` method has been removed from every individual module. Use `DriveKit.reset()` as your single reset point across all modules.

| Removed in v3.0                   | What to do instead           |
| --------------------------------- | ---------------------------- |
| DriveKitDriverData.reset()        | Call DriveKit.shared.reset() |
| DriveKitChallenge.reset()         | Call DriveKit.shared.reset() |
| DriveKitCoaching.reset()          | Call DriveKit.shared.reset() |
| DriveKitDriverAchievement.reset() | Call DriveKit.shared.reset() |
| DriveKitGroup.reset()             | Call DriveKit.shared.reset() |
| DriveKitTripAnalysis.reset()      | Call DriveKit.shared.reset() |
| DriveKitVehicle.reset()           | Call DriveKit.shared.reset() |

## DriveKitTripAnalysis

Several one-off methods have been merged into a single, structured call: `getCurrentTripInfo()`. This reduces the number of calls you need to make and gives you all the context about the current trip in one place.

| Removed in v3.0                     | What to do instead                                                                                         |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| getCurrentStartMode() -> StartMode? | getCurrentTripInfo() → access .startMode                                                                   |
| getCurrentTripStartDate() -> Date?  | getCurrentTripInfo() → access .startDate                                                                   |
| getLastTripPoint() -> TripPoint?    | getLastTripPointOfCurrentTrip()                                                                            |
| getTripResponseStatus(\_:)          | tripFinished(responseStatus:) — see [TripResponseStatus](/trip-analysis/ios/references#tripresponsestatus) |

### TripListener protocol — Updated Methods & Types

The `TripListener` protocol has been redesigned for clarity. The new methods provide richer state objects, so you get more context with less code.

#### **Method Replacements**

| Removed in v3.0                                                     | What to do instead                                           |
| ------------------------------------------------------------------- | ------------------------------------------------------------ |
| tripStarted(startMode: StartMode)                                   | tripRecordingConfirmed(state: DKTripRecordingConfirmedState) |
| tripCancelled(cancelTrip: CancelTrip)                               | tripRecordingCanceled(state: DKTripRecordingCanceledState)   |
| func tripFinished(post: PostGeneric, response: PostGenericResponse) | tripFinished(responseStatus: TripResponseStatus)             |

#### **Removed Classes & Enums**

These types were tightly coupled to the old listener design. They are no longer needed.

| Removed type in v3.0        | What to do instead                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| CancelTrip (enum)           | State is now carried by [DKTripRecordingCanceledState](/trip-analysis/ios/references#dktriprecordingcanceledstate) |
| PostGeneric (class)         | No longer needed - the new API handles this internally                                                             |
| PostGenericResponse (class) | Replaced by the cleaner [TripResponseStatus](/trip-analysis/ios/references#tripresponsestatus)                     |

## DriveKitVehicle

A property has been converted to a method to support electric vehicle context.

| Removed in v3.0                              | What to do instead                   | Class             |
| -------------------------------------------- | ------------------------------------ | ----------------- |
| DKVehicleCategory.liteConfigDqIndex: String? | getLiteConfigDqIndex(isElectricCar:) | DKVehicleCategory |

## Data Access Layer (DB)

### DriveKitDBAchievementAccess

| Removed in v3.0 | What to do instead                          | Module          |
| --------------- | ------------------------------------------- | --------------- |
| .legacy         | No longer used - remove any reference to it | DKRankingPeriod |

### DriveKitDBTripAccess

The trip data classes have been renamed to follow the DK naming convention used across the SDK. This brings consistency and avoids naming collisions in your project.

| Removed in v3.0         | What to do instead                                                                                                                                                |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Trip (+ nested classes) | Use DKTrip - see [reference documentation](/trip-analysis/ios/references#dktrip)                                                                                  |
| Route                   | Use DKRoute - see [reference documentation](https://docs.google.com/spreadsheets/d/1RYJ3e4FpzzB4jBxvjsHZefsxgwJO9GhFvexIywrV8Zo/edit?gid=201186400#gid=201186400) |

## UI Modules

### DriveKitCommonUI

| Removed in v3.0                                   | What to do instead                                             |
| ------------------------------------------------- | -------------------------------------------------------------- |
| CircularProgressView\.getScoreColor(value:steps:) | ConfigurationCircularProgressView\.getScoreColor(value:steps:) |
| ScoreType (enum)                                  | DKScoreType - same enum, new consistent name                   |
| DKScoreType.image() -> UIImage?                   | DKScoreType.gaugeImage() - clearer intent                      |

### DriveKitPermissionsUtilsUI

Logging control is now centralized in the DriveKit Core module — no longer split across the UI module.

| Removed in v3.0               | What to do instead                                 |
| ----------------------------- | -------------------------------------------------- |
| showDiagnosisLogs             | DriveKit.shared.isLoggingEnabled()                 |
| configureDiagnosisLogs(show:) | DriveKit.shared.enableLogging() / disableLogging() |
| configureBluetooth(needed:)   | Removed - no replacement needed, safe to delete    |

#### DriveKitVehicleUI

| Removed in v3.0                             | What to do instead                                |
| ------------------------------------------- | ------------------------------------------------- |
| configureVehiclePickerExtraStep(extraStep:) | Removed - no replacement, safe to delete the call |
| DKVehiclePickerExtraStep (protocol)         | Removed - safe to delete any conformance          |

### DriveKitDriverDataTimelineUI

| Removed in v3.0                                     | What to do instead           |
| --------------------------------------------------- | ---------------------------- |
| DriveKitDriverDataTimelineUI.scores: \[DKScoreType] | Use DriveKitUI.shared.scores |


# Android

## Requirements

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

The [latest](https://docs.drivequant.com/release-notes/changelog/android) DriveKit SDK version is configured with these attributes: &#x20;

| Android SDK version property | API level       |
| ---------------------------- | --------------- |
| minSdkVersion                | 26 (Android 8)  |
| compileSdkVersion            | 36 (Android 16) |
| targetSdkVersion             | 36 (Android 16) |

{% hint style="info" %}
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.
{% endhint %}

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

| Library                | Version |
| ---------------------- | ------- |
| 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.3.0  |
| Car App                | 1.7.0   |

{% hint style="warning" %}
DriveKit uses [key-value backup](https://developer.android.com/guide/topics/data/keyvaluebackup). If you use [Auto Backup](https://developer.android.com/guide/topics/data/autobackup), you need to add `android:fullBackupOnly` in your [Manifest](https://developer.android.com/guide/topics/manifest/application-element#fullBackupOnly).
{% endhint %}


# 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:

{% hint style="info" %}
You can also clone the following [repository](https://github.com/DriveQuantPublic/drivekit-quickstart-android), configure the required credentials then simply run the quickstart app!
{% endhint %}

## Set up your project

The DriveKit SDK is now available on the Maven Central repository starting from `2.24.0`.

## Add the TripAnalysis module to your project <a href="#docs-internal-guid-f66fad15-7fff-6cbc-8666-0a1c36fd2b31" id="docs-internal-guid-f66fad15-7fff-6cbc-8666-0a1c36fd2b31"></a>

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

{% tabs %}
{% tab title="build.gradle.kts" %}

```gradle
dependencies {
    implementation("com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version")
}
```

{% endtab %}

{% tab title="build.gradle" %}

```gradle
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version'
}
```

{% endtab %}
{% endtabs %}

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

{% hint style="info" %}
Replace `$drivekit_version`with the latest release version of DriveKit on the [changelog](https://docs.drivequant.com/release-notes/changelog/android) page.
{% endhint %}

{% hint style="warning" %}
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 [Advanced configurations](https://docs.drivequant.com/get-started-drivekit/android/advanced-configurations) part.
{% endhint %}

## 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:

{% code title="AndroidManifest.xml" %}

```xml
<manifest ... >
    ...
    <application android:allowBackup="true" ... >
        ...
    </application>
</manifest>
```

{% endcode %}

{% hint style="info" %}
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* [*https://developer.android.com/identity/data/autobackup#IncludingFiles*](https://developer.android.com/identity/data/autobackup#IncludingFiles)*)*.
{% endhint %}

All other diagnosis events (described [here](https://docs.drivequant.com/push-services/push-diagnosis-data#sample-message)) will be provided regardless of the `allowBackup` configuration.

{% hint style="warning" %}
In case of Manifest merging issue with DriveKit, please refer to the [Troubleshooting](/get-started-drivekit/android/troubleshooting) page.
{% endhint %}

## 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:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun setApiKey(key: String)
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun setUserId(userId: String)
```

{% endtab %}
{% endtabs %}

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.

{% hint style="warning" %}
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 ([GUID](https://www.guidgenerator.com/online-guid-generator.aspx)) for each of your users.
{% endhint %}

{% hint style="danger" %}
DriveKit SDK will not work until you set the API key and the userId.
{% endhint %}

## 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`:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun activateAutoStart(activate: Boolean)
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="build.gradle.kts" %}

```gradle
dependencies {
    implementation("com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version")
    implementation("com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version")
}
```

{% endtab %}

{% tab title="build.gradle" %}

```gradle
dependencies {
    implementation "com.drivequant.drivekit:drivekit-trip-analysis:$drivekit_version"
    implementation "com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Replace $drivekitui\_version with the latest release version of graphical modules on the [changelog](https://docs.drivequant.com/release-notes/changelog/ui-android) page.
{% endhint %}

Then, call the following code in your project:

```kotlin
PermissionsUtilsUI.showPermissionViews(context, object: PermissionViewListener {
    override fun onFinish() {
        // Code called when requested permissions are properly granted.
    }
})
```

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:

* Configure the [Core](/get-started-drivekit/android/advanced-configurations) and [TripAnalysis](/trip-analysis/android) modules with advanced settings. For example, [customize the notification displayed during a trip analysis](/trip-analysis/android/trip-management#configure-the-trip-notification-content),[alert the user once a trip has been analyzed by the DriveQuant servers by displaying a notification](/trip-analysis/android/triplistener), activate the [crash detection](/trip-analysis/android/crash-detection#principle), 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 [Driver Data](https://docs.drivequant.com/driver-data/android/get-started) module.
* Associate each trip to a vehicle that you can configure with the [Vehicle](https://docs.drivequant.com/vehicle/android/get-started) module.
* Improve user retention by organizing [challenges](/challenge/introduction), display [ranking](/driver-achievement/android/get-started#get-ranking) with the community, show which [badges](/driver-achievement/android/get-started#get-badges) the driver earned, etc.


# 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.&#x20;

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:

```xml
<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>

```

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

```kotlin
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.
    }
}

```

## Check your configuration

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

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun isConfigured(): Boolean
```

{% endtab %}
{% endtabs %}

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:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun isUserConnected(): Boolean
```

{% endtab %}
{% endtabs %}

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:&#x20;

{% tabs %}
{% tab title="DriveKitLog" %}

```kotlin
fun getLogUriFile(context: Context): Uri?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.
{% endhint %}

Disable logging by calling the following method on `DriveKit` class:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun disableLogging(showInConsole: Boolean = true)
```

{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun enableLogging(logPath: String = "/DriveKit", showInConsole: Boolean = true)
```

{% endtab %}
{% endtabs %}

The DriveKit log ZIP file includes a configuration file in JSON format.&#x20;

This file lists the values of all configuration parameters for the DriveKit SDK installed in your user's app.

This [document](https://docs.google.com/spreadsheets/d/1cdU7jM3gLEyFBWpaHf5OH9SSRZkm38YACrohn0Cr-t4/edit?usp=sharing) provides a detailed overview of all the configuration entries included in the config file, along with their definitions and expected values.

## **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.&#x20;

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.

{% hint style="info" %}
Event changes callbacks may not be fired in real time due to technical restrictions of Android.
{% endhint %}

### DKDeviceConfigurationListener

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

```kotlin
interface DKDeviceConfigurationListener {
    fun onDeviceConfigurationChanged(event: DKDeviceConfigurationEvent)
}
```

### Add a listener

To add a listener and get informed for [device configuration events](#docs-internal-guid-959f39f9-7fff-5ef1-6859-d0cd591eb82e), you can call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun addDeviceConfigurationListener(listener: DKDeviceConfigurationListener)
```

{% endtab %}
{% endtabs %}

### Remove a listener

To remove a specific listener, call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun removeDeviceConfigurationListener(listener: DKDeviceConfigurationListener)
```

{% endtab %}
{% endtabs %}

### Remove all listeners

To remove all listeners, call the following method:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun removeAllDeviceConfigurationListeners()
```

{% endtab %}
{% endtabs %}

### DKDeviceConfigurationEvent <a href="#docs-internal-guid-959f39f9-7fff-5ef1-6859-d0cd591eb82e" id="docs-internal-guid-959f39f9-7fff-5ef1-6859-d0cd591eb82e"></a>

`DKDeviceConfigurationEvent` is a sealed class that describes a device configuration change event:&#x20;

<pre class="language-kotlin"><code class="lang-kotlin">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()
<strong>	data class AutoResetPermission(val isValid: Boolean) : DKDeviceConfigurationEvent()
</strong>	data class AppBatteryOptimisation(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class LocationSensor(val isValid: Boolean) : DKDeviceConfigurationEvent()
	data class BluetoothSensor(val isValid: Boolean) : DKDeviceConfigurationEvent()
}
</code></pre>

Possible events are:

<table><thead><tr><th width="283">Value</th><th>Description</th></tr></thead><tbody><tr><td>LocationPermission</td><td>Location permission status changed</td></tr><tr><td>ActivityPermission</td><td>Activity Recognition permission status changed</td></tr><tr><td>NearbyDevicesPermission</td><td>Nearby Devices permission status changed</td></tr><tr><td>NotificationPermission</td><td>Notification permission status changed</td></tr><tr><td>AutoResetPermission</td><td>Auto-reset permission status changed</td></tr><tr><td>AppBatteryOptimization</td><td>Battery Optimization app status changed</td></tr><tr><td>LocationSensor</td><td>Location sensor status changed</td></tr><tr><td>BluetoothSensor</td><td>Bluetooth sensor status changed </td></tr></tbody></table>

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`:

<table><thead><tr><th width="288.3333333333333">Event</th><th width="106" align="center">Criticality</th><th>Consequence if value is false</th></tr></thead><tbody><tr><td>LocationPermission</td><td align="center">🔴</td><td>No trip recording if app has no access to GPS sensor</td></tr><tr><td>ActivityPermission</td><td align="center">🟡</td><td>Poor trip detection</td></tr><tr><td>NearbyDevicesPermission</td><td align="center">🟡</td><td>No trip detection based on beacon or Bluetooth system</td></tr><tr><td>NotificationPermission</td><td align="center">🟢</td><td>Your application cannot send notification to the user if the permission is revoked.</td></tr><tr><td>AutoResetPermission</td><td align="center">🟢</td><td>Revocation of all permissions if app is not opened for 3 months.</td></tr><tr><td>AppBatteryOptimization</td><td align="center">🟡</td><td>Poor trip detection, application may be killed in background</td></tr><tr><td>LocationSensor</td><td align="center">🔴</td><td>No trip recording if location sensor is disabled</td></tr><tr><td>BluetoothSensor</td><td align="center">🟡</td><td>No trip detection based on beacon or Bluetooth system</td></tr></tbody></table>

## **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:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun getUserInfo(
        listener: GetUserInfoQueryListener,
        synchronizationType: SynchronizationType = SynchronizationType.DEFAULT
)
```

{% endtab %}
{% endtabs %}

## **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 :

{% tabs %}
{% tab title="DriveKit" %}
{% code fullWidth="false" %}

```kotlin
fun updateUserInfo(
        firstname: String? = null,
        lastname: String? = null,
        pseudo: String? = null,
        listener: UpdateUserInfoQueryListener
)
```

{% endcode %}
{% endtab %}
{% endtabs %}

## **Update UserId**

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

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun updateUserId(userId: String)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To be able to check whenever `userId` got updated and catch the update status you have to use [DriveKitListener](/get-started-drivekit/android/references#drivekitlistener) listener.
{% endhint %}

## Account deletion

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

&#x20;The deletion can be done instantly or with delay.&#x20;

* In the first case, when the method is called, the account is instantly deleted.&#x20;
* 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:

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun deleteAccount(instantDeletion: Boolean = false)
```

{% endtab %}
{% endtabs %}

`instantDeletion` can have 2 values:&#x20;

* `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.

{% hint style="info" %}
Your team needs to have the deletion feature activated to use this method. Please contact DriveQuant if you need it.
{% endhint %}

{% hint style="info" %}
To be able to check whenever the account deletion is complete, you have to use the [DriveKitListener](https://docs.drivequant.com/get-started-drivekit/android/references#drivekitlistener) interface.
{% endhint %}

{% hint style="warning" %}
You should restore the DriveKit API key in the `onAccountDeleted()` callback only when the status value is `SUCCESS`.
{% endhint %}

## Retrieving the installation identifier <a href="#retrieving-the-installation-identifier" id="retrieving-the-installation-identifier"></a>

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:&#x20;

* 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.

{% hint style="info" %}
The installationId uses the UUID format. Example: `123e4567-e89b-12d3-a456-426614174000`
{% endhint %}

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

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
var installationId: String?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The returned installationId will be `null` as long as the user is not authenticated to DriveKit.

For example, you can retrieve the identifier after the `onConnected()` callback is triggered. (Read more about the [DriveKitListener](/get-started-drivekit/android/references#drivekitlistener))
{% endhint %}

## Reset

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

{% tabs %}
{% tab title="DriveKit" %}

```kotlin
fun reset()
```

{% endtab %}
{% endtabs %}

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


# References

## DriveKitListener <a href="#drivekitlistener" id="drivekitlistener"></a>

DriveKitListener is an interface that can be passed as a parameter during the DriveKit Core module [initialization](https://docs.drivequant.com/get-started-drivekit/android#drivekit-initialization). It gives useful events about the user lifecycle.

```kotlin
interface DriveKitListener {
    fun onConnected()
    fun onDisconnected()
    fun onAuthenticationError(errorType: RequestError)
    fun userIdUpdateStatus(status: UpdateUserIdStatus, userId:String?)
    fun onAccountDeleted(status: DeleteAccountStatus)
}
```

| Method                                                           | Description                                                                                                 |
| ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `onConnected()`                                                  | The user has been successfully logged                                                                       |
| `onDisconnected()`                                               | The user has been disconnected (manual logout or the account is disabled/deleted)                           |
| `onAuthenticationError(errorType: RequestError)`                 | The login has failed due to a [`RequestError`](#deviceconfigevent)                                          |
| `userIdUpdateStatus(status: UpdateUserIdStatus, userId:String?)` | The update userId request has been processed with a [`UpdateUserIdStatus`](#updateuseridstatus) state value |
| `onAccountDeleted(status: DeleteAccountStatus)`                  | The delete account request has been processed with a `DeleteAccountStatus` state value                      |

## UpdateUserIdStatus

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

```kotlin
enum class UpdateUserIdStatus {
    UPDATED, FAILED_TO_UPDATE, INVALID_USER_ID, ALREADY_USED, SAVED_FOR_REPOST
}
```

| Value              | Description                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------ |
| `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                                                |

## RequestError <a href="#deviceconfigevent" id="deviceconfigevent"></a>

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

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

| Value             | Description                                                                                                          |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| `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.                      |

## DeleteAccountStatus

`DeleteAccountStatus` is an enum that describes the deletion status. It can have 3 values:&#x20;

* `SUCCESS`: Account deleted successfully&#x20;
* `FAILED_TO_DELETE`: Account not deleted, an error has occurred&#x20;
* `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`

## DKPeriod

`DKPeriod` indicates the aggregation size of each timeline object. It is an enum with the following values:

<table><thead><tr><th width="175.5">Value</th><th>Description</th></tr></thead><tbody><tr><td>WEEK</td><td>Timeline data is aggregated week by week</td></tr><tr><td>MONTH</td><td>Timeline data is aggregated month by month</td></tr><tr><td>YEAR</td><td>Timeline data is aggregated year by year</td></tr></tbody></table>

## RoadContext

`RoadContext` indicates the kind of roads where the data was gathered. It is an enum with the following values:

<table><thead><tr><th width="286">Value</th><th>Description</th></tr></thead><tbody><tr><td>TRAFFIC_JAM</td><td>The targeted driver was in traffic jams</td></tr><tr><td>HEAVY_URBAN_TRAFFIC</td><td>The targeted driver was in dense city roads</td></tr><tr><td>CITY</td><td>The targeted driver was in light traffic city roads</td></tr><tr><td>SUBURBAN</td><td>The targeted driver was in suburban or countryside roads</td></tr><tr><td>EXPRESSWAYS</td><td>The targeted driver was in express ways</td></tr></tbody></table>


# Android 15 Migration guide

## 1 - Check major changes

Android offers a clear and exhaustive [documentation](https://developer.android.com/about/versions/15) listing the new features and changes related to Android 15.

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

{% hint style="warning" %}
You must consider the two main categories of behaviours changes related to Android 15:

* [Behavior changes: all apps](https://developer.android.com/about/versions/15/behavior-changes-all)
* [Behavior changes: Apps targeting Android 15 or higher](https://developer.android.com/about/versions/15/behavior-changes-15)
  {% endhint %}

## 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.

DriveQuant recommends to specifically pay attention about the [Edge-to-edge enforcement](https://developer.android.com/about/versions/15/behavior-changes-15#edge-to-edge) which is now enabled by default when your app is targeting Android 15.

{% hint style="info" %}
If your app is not ready to support edge-to-edge, you can disable it by using the [`windowOptOutEdgeToEdgeEnforcement`](https://developer.android.com/reference/android/R.attr#windowOptOutEdgeToEdgeEnforcement)attribute.
{% endhint %}

## 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.&#x20;

{% hint style="info" %}
The latest DriveKit versions are listed in the changelog:

* [For internal modules](/release-notes/changelog/android)&#x20;
* [For UI modules](/release-notes/changelog/ui-android)
  {% endhint %}

## 5 - Tests 🚗

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 [DriveQuant's app](https://play.google.com/store/apps/details?id=com.drivequant) and/or the [DriveKit Demo App](https://github.com/DriveQuantPublic/drivekit-ui-android); which already support Android 15.&#x20;

If you experience any problems with DriveKit, please contact [us](mailto:contact@drivequant.com).


# Android 14 Migration guide

## 1 - Check major changes

Android offers a clear and exhaustive [documentation](https://developer.android.com/about/versions/14) listing the new features and changes related to Android 14.

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

{% hint style="warning" %}
You must consider the two main categories of behaviours changes related to Android 14:

* [Behavior changes: all apps](https://developer.android.com/about/versions/14/behavior-changes-all)
* [Behavior changes: Apps targeting Android 14 or higher](https://developer.android.com/about/versions/14/behavior-changes-14)
  {% endhint %}

## 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:

* [Foreground services type are required](https://developer.android.com/about/versions/14/changes/fgs-types-required)
* [Restrictions to implicit and pending intents](https://developer.android.com/about/versions/14/behavior-changes-14#safer-intents)

## 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.&#x20;

{% hint style="info" %}
The latest DriveKit versions are listed in the changelog:

* [For internal modules](/release-notes/changelog/android)&#x20;
* [For UI modules](/release-notes/changelog/ui-android)
  {% endhint %}

## 5 - Tests 🚗

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 [DriveQuant's app](https://play.google.com/store/apps/details?id=com.drivequant) and/or the [DriveKit Demo App](https://github.com/DriveQuantPublic/drivekit-ui-android); which already support Android 14.&#x20;

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


# 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:

{% tabs %}
{% tab title="AndroidManifest.xml" %}

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

{% endtab %}
{% endtabs %}

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/xml`folder:

{% tabs %}
{% tab title="merged\_data\_extraction\_rules" %}

```xml
<?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>
```

{% endtab %}
{% endtabs %}

## `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:

{% tabs %}
{% tab title="AndroidManifest.xml" %}

<pre class="language-xml"><code class="lang-xml">&#x3C;application
        android:fullBackupContent="<a data-footnote-ref href="#user-content-fn-1">@xml/merged_backup_rules</a>"
        tools:replace="android:fullBackupContent" 
        (…)
/>
</code></pre>

{% endtab %}
{% endtabs %}

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/xml`folder:

{% code title="merged\_backup\_rules.xml" fullWidth="false" %}

```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>
```

{% endcode %}

{% hint style="warning" %}
If you have both **dataExtractionRules** and **fullBackupContent** merge issues, you have to declare the two attrbutes as follows:

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

{% endhint %}

## `BackupAgent` merge issue

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

> ```xml
> 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.&#x20;

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:&#x20;

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

[^1]:


# DriveKit 3.0 migration guide

Migration guide for DriveKit 3.0 on Android platform

## What's changed in v3.0?

### Introduction

Version 3.0 of the DriveKit SDK contains breaking changes: all methods that were marked as deprecated during the past year have been permanently removed.

This guide lists every removed element alongside its recommended replacement, organized by module.&#x20;

Following these steps will keep your integration stable and future-proof.

{% hint style="info" %}
This version also features a newly available callback to retrieve the beacon detected and confirmed during trip recording which will not be presented in this migration guide.
{% endhint %}

### How to use this guide

Each section maps to an SDK module. For every removed element, you'll find:

* The exact method, class, or property that was removed
* The recommended drop-in replacement to use instead

## Module-level reset() Methods

The reset() method has been removed from every individual module. Use DriveKit.reset() as your single reset point across all modules.

| Removed in v3.0                   | What to do instead    |
| --------------------------------- | --------------------- |
| DriveKitDriverData.reset()        | Call DriveKit.reset() |
| DriveKitChallenge.reset()         | Call DriveKit.reset() |
| DriveKitCoaching.reset()          | Call DriveKit.reset() |
| DriveKitDriverAchievement.reset() | Call DriveKit.reset() |
| DriveKitGroup.reset()             | Call DriveKit.reset() |
| DriveKitTripAnalysis.reset()      | Call DriveKit.reset() |
| DriveKitVehicle.reset()           | Call DriveKit.reset() |

## DriveKitTripAnalysis

Several one-off methods have been merged into a single, structured call: `getCurrentTripInfo()`. This reduces the number of calls you need to make and gives you all the context about the current trip in one place.

| Removed in v3.0                      | What to do instead                                                                                |
| ------------------------------------ | ------------------------------------------------------------------------------------------------- |
| getCurrentStartMode(): StartMode?    | getCurrentTripInfo() → access `startMode`                                                         |
| getCurrentTripStartDate(): Date?     | getCurrentTripInfo() → access `startDate`                                                         |
| getLastTripPoint(): TripPoint?       | getLastTripPointOfCurrentTrip()                                                                   |
| getTripResponseStatus(tripResponse:) | tripFinished(result: TripResult) - see [TripResult](/trip-analysis/android/references#tripresult) |
| isConfigured()                       | isInitialized property - direct boolean access                                                    |

### TripListener interface — Updated Methods & Types

The TripListener interface has been redesigned for clarity. The new methods provide richer state objects, so you get more context with less code.

#### Method Replacements

| Removed in v3.0                                                | What to do instead                                             |
| -------------------------------------------------------------- | -------------------------------------------------------------- |
| tripStarted(startMode: StartMode)                              | tripRecordingConfirmed(state: DKTripRecordingConfirmedState)   |
| tripCancelled(cancelTrip: CancelTrip)                          | tripRecordingCanceled(state: DKTripRecordingCanceledState)     |
| tripFinished(post: PostGeneric, response: PostGenericResponse) | tripFinished(responseStatus: TripResponseStatus)               |
| onDeviceConfigEvent(deviceConfigEvent: DeviceConfigEvent)      | DKDeviceConfigurationListener - a dedicated listener interface |

#### Removed Classes & Enums

These types were part of the legacy event model and are no longer needed.

<table data-full-width="false"><thead><tr><th>Removed type</th><th>What to do instead</th></tr></thead><tbody><tr><td>DeviceConfigEvent (class)</td><td>Handled by the new <a href="/pages/kWvK0sz843cs0hEu9ZNH#dkdeviceconfigurationlistener">DKDeviceConfigurationListener</a></td></tr><tr><td>CancelTrip (enum)</td><td>State now lives in <a href="/pages/-LnMH5ErH5WNrLs46vVd#dktriprecordingcanceledstate">DKTripRecordingCanceledState</a></td></tr><tr><td>PostGeneric (class)</td><td>No longer needed internally</td></tr><tr><td>PostGenericResponse (class)</td><td>Replaced by <a href="/pages/-LnMH5ErH5WNrLs46vVd#tripresult">TripResult</a></td></tr><tr><td>RecorderState (class)</td><td>Referenced CancelTrip - both are now gone</td></tr><tr><td>TripResponseStatus (class)</td><td>Replaced by the cleaner <a href="/pages/-LnMH5ErH5WNrLs46vVd#tripresult">TripResult</a></td></tr><tr><td>TripAnalysedReceiver (class)</td><td>Use tripFinished() and tripRecordingCanceled() in <a href="/pages/Qj7kT6FTAoTfYnGbMmmA">TripListener</a> instead</td></tr></tbody></table>

### TripNotification

The following TripNotification parameters are no longer used by the SDK. Simply remove them from your notification configuration — no replacement needed.

| Removed parameter            | Action               |
| ---------------------------- | -------------------- |
| gpsAccuracyContent           | Remove the parameter |
| gpsAccuracyButtonContent     | Remove the parameter |
| highSpeedTripDetectedContent | Remove the parameter |
| noGpsIconId                  | Remove the parameter |

## DriveKitVehicle&#x20;

These method wrappers have been removed in favor of idiomatic Kotlin property and function access.

| Removed in v3.0                    | What to do instead                                           |
| ---------------------------------- | ------------------------------------------------------------ |
| VehicleEngineIndex.getValue()      | Use .value directly - e.g. VehicleEngineIndex.GASOLINE.value |
| VehicleEngineIndex.getEnumByName() | Use VehicleEngineIndex.valueOf(name)                         |

## DriveKitDriverAchievement

| Removed in v3.0      | What to do instead                          |
| -------------------- | ------------------------------------------- |
| RankingPeriod.LEGACY | No longer used - remove any reference to it |


# Introduction

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

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 [push data service](/push-services/push-data) to a third-party server.

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.&#x20;

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:&#x20;

* offer a driver assistance solution integrated into your application;&#x20;
* access accurate data to speed up claims management.

{% hint style="info" %}
We recommend you to test this component in the [DriveKit Demo App](/#the-drivekit-demo-app) before you integrate it in your application.
{% endhint %}


# iOS


# Permissions

## Configure Capabilities

1. Go to the **Capabilities** tab of your target settings.
2. Turn on **Background Modes** and enable **Location updates**.

![](/files/-LnDVIhKDeg5HfoUYBVI)

## Configure permissions

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

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:

```swift
DKDiagnosisHelper.shared.requestPermission(.location)
```

## Motion and Fitness permission

By default, the SDK incorporates the permission request to access Motion and Fitness. This allows for improved transportation mode recognition through the use of [activity recognition](https://developer.apple.com/documentation/coremotion/cmmotionactivity) based on motion properties.

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:

```swift
DriveKitTripAnalysis.shared.activateActivityRecording(false)
```


# 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.&#x20;

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:

```swift
DriveKitTripAnalysis.shared.activateAutoStart(enable: true)
```

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

```swift
DriveKitTripAnalysis.shared.activateAutoStart(enable: false)
```

{% hint style="warning" %}
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 [`cancelTrip`](#cancel-a-trip) method.
{% endhint %}

### Manually start a trip

You can start a trip by calling the following method:

```swift
DriveKitTripAnalysis.shared.startTrip()
```

{% hint style="info" %}
If a trip's already started, calling this method will have no effect.
{% endhint %}

### Stop a trip

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

```swift
DriveKitTripAnalysis.shared.stopTrip()
```

{% hint style="info" %}
If a vehicle stops longer than the [timeout configured](#custom-stop-timeout), the trip will be stopped automatically.
{% endhint %}

{% hint style="info" %}
If there is no running trip, calling this method will have no effect.
{% endhint %}

### Cancel a trip

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

```swift
DriveKitTripAnalysis.shared.cancelTrip()
```

{% hint style="info" %}
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.
{% endhint %}

## 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:

```swift
DriveKitTripAnalysis.shared.setVehicle(vehicle: TripVehicle?)
```

A detailed description of vehicle parameter is available [here](/trip-analysis/ios/references#tripvehicle).

{% hint style="info" %}
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`
  {% endhint %}

## SDK recorder state

Two methods are available to determine SDK state.

```swift
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:

```swift
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](broken://pages/-LmyMHEUlo10HxloqP6X#custom-stop-timeout) 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.

{% hint style="info" %}

* 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`).
  {% endhint %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func getCurrentTripInfo() -> DKTripInfo?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The method can return `nil` if there is no trip currently recording.
{% endhint %}

### DKTripInfo

| Property    | Type        | Description                                                                                                                                                                                                                                                     |
| ----------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| localTripId | `String`    | <p>Local and unique trip identifier generated by DriveKit SDK.</p><p>⚠️ It is different from the <code>itinId</code> property returned in the Trip object. <code>itinId</code> corresponds to the unique trip identifier generated after the data analysis.</p> |
| date        | `Date`      | <p>Start date of the trip analysis. </p><p>⚠️ It is different from the startDate property returned in the <a href="/pages/-LnH2v8JiN0ZC4OialHx#trip">Trip</a> object.</p>                                                                                       |
| startMode   | `StartMode` | The [StartMode](/trip-analysis/ios/references#startmode) which triggered the trip analysis.                                                                                                                                                                     |

## 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.&#x20;

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:

```swift
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.&#x20;

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:

```swift
DriveKitTripAnalysis.shared.setStopTimeOut(timeOut: 180)
```

{% hint style="warning" %}
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.
{% endhint %}

## Custom max speed before cancellation

A trip being recorded is automatically cancelled if the speed is above a given value. The DriveKit SDK allows you to modify the threshold.

By default, the trip recording is canceled with the [highSpeed](/trip-analysis/ios/references#dktripcancelationreason) trip cancellation reason when speed is above 200 km/h. This value can be tuned according to your need and you can choose any double values between 50 and 1500 km/h by calling the following code:

{% tabs %}
{% tab title="Swift" %}

```kotlin
let desiredMaxSpeed = 300.0 // in km/h
DriveKitTripAnalysis.shared.autoCancelTripMaxSpeed = desiredMaxSpeed
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If a value greater than 1500 is set, the value will be forced to 1500.

If a value lower than 50 is set, the value will be forced to 50.
{% endhint %}

## 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:

```swift
DriveKitTripAnalysis.shared.tripSharing.isAvailable()
```

### Create a link

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

```swift
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

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The link has been successfully created. Information is returned in <code>data</code>.</td></tr><tr><td>activeLinkAlreadyExists</td><td><p>A link already exists for this user.</p><p>Information returned in <code>data</code> is nil.</p><p></p><p>💡 You have to call the method to <a href="#retrieve-a-valid-sharing-link">retrieve an existing link</a> in your workflow.</p></td></tr><tr><td>error</td><td><p>An error occurred, for instance when the user has no network.</p><p>Information returned in <code>data</code> is nil.</p></td></tr><tr><td>userNotConnected</td><td>The user is not yet connected to DriveKit. Information returned in <code>data</code> is nil.</td></tr><tr><td>invalidDuration</td><td>An error occurred when trying to create a link. The duration parameter must be strictly greater than 0. Information returned in <code>data</code> is nil.</td></tr><tr><td>unauthenticated</td><td><p>The user has been disconnected.</p><p>Information returned in <code>data</code> is nil.</p></td></tr><tr><td>forbidden</td><td><p>Your API key is <strong>not</strong> allowed to use the feature.</p><p>Information returned in <code>data</code> is nil.</p></td></tr></tbody></table>

#### 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:

```swift
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

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The link has been successfully retrieved. Information is returned in <code>data</code>.</td></tr><tr><td>failedToGetCacheOnly</td><td>An error occurred when trying to retrieve a link. Locally trip sharing link, if exists, is returned in data.</td></tr><tr><td>noActiveLink</td><td><p>There is no active link for the user.</p><p>Information returned in <code>data</code> is nil.</p></td></tr><tr><td>userNotConnected</td><td>The user is not yet connected to DriveKit. Information returned in <code>data</code> is nil.</td></tr><tr><td>unauthenticated</td><td><p>The user has been disconnected.</p><p>Information returned in <code>data</code> is nil.</p></td></tr><tr><td>forbidden</td><td><p>Your API key is <strong>not</strong> allowed to use the feature.</p><p>Information returned in <code>data</code> is nil.</p></td></tr></tbody></table>

### Revoke a trip sharing link

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

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

#### RevokeTripSharingLinkStatus

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The link has been successfully revoked.</td></tr><tr><td>noActiveLink</td><td>There is no active link for the user.</td></tr><tr><td>error</td><td>An error occurred when trying to revoke the link.</td></tr><tr><td>userNotConnected</td><td>The user is not yet connected to DriveKit.</td></tr><tr><td>unauthenticated</td><td>The user has been disconnected.</td></tr><tr><td>forbidden</td><td>Your API key is <strong>not</strong> allowed to use the feature.</td></tr></tbody></table>

## Sharing data during the trip

{% hint style="warning" %}
This feature allows you to share to the server the location of a driver during all his trips. It is different from the [trip sharing with a link](#share-trips-with-a-link) feature where the user chooses to share his trips for a certain duration, thanks to a link showing his current trip on a map.
{% endhint %}

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:

```swift
DriveKitTripAnalysis.shared.enableSharePosition(enable: true)
```

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

```swift
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.&#x20;
* 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:

```swift
DriveKitTripAnalysis.shared.monitorPotentialTripStart = true
```

Once the feature is enabled, events will be available in the [TripListener](/trip-analysis/ios/triplistener) `potentialTripStart()`  callback.

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.&#x20;

The returned location type is [DKTripLocation](/trip-analysis/ios/references#dktriplocation).

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

{% hint style="info" %}
The last trip corresponds to the last trip recorded by the DriveKit SDK, regardless of the mode of transport used.
{% endhint %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func getLastTripLocation() -> DKTripLocation?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.
  {% endhint %}

### Get Last Vehicle Trip Location

This function returns the location of the end of the last vehicle trip.&#x20;

The returned location type is [DKTripLocation](/trip-analysis/ios/references#dktriplocation).

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func getLastVehicleTripLocation() -> DKTripLocation?
```

{% endtab %}
{% endtabs %}


# 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.

{% hint style="info" %}
The trip recording lifecycle is exhaustively described in [Trip recording lifecycle](/get-started-drivekit/trip-recording-lifecycle) part.
{% endhint %}

## Add a TripListener

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func addTripListener(_ tripListener: TripListener)
```

{% endtab %}
{% endtabs %}

You can remove a specific listener using the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func removeTripListener(_ tripListener: TripListener)
```

{% endtab %}
{% endtabs %}

To remove all TripListeners objects:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func removeAllTripListeners()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.).
{% endhint %}

{% hint style="warning" %}
Do not forget to remove your `TripListener` objects when you don't need it anymore.
{% endhint %}

`TripListener` interface includes several methods to implement:

| Method                                                                                                                                                                                                                                                                                   | Description                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tripRecordingStarted(state: DKTripRecordingStartedState)                                                                                                                                                                                                                                 | <p>Immediately called when a trip recording starts.</p><p>This callback is triggered:</p><ul><li>after calling the DriveKit SDK's <a href="/pages/RQWwwTuNsEs1VslSzScZ#manually-start-a-trip"><code>startTrip()</code></a> method.</li><li>after automatic trip detection.</li></ul><p><code>DKTripRecordingStartedState</code> object is described <a href="/pages/-LnH2v8JiN0ZC4OialHx#dktriprecordingstartedstate">here</a>.</p> |
| tripRecordingConfirmed(state: DKTripRecordingConfirmedState)                                                                                                                                                                                                                             | <p>Called each time a trip is confirmed.<br><code>DKTripRecordingConfirmedState</code> object is described <a href="/pages/-LnH2v8JiN0ZC4OialHx#dktriprecordingconfirmedstate">here</a>.</p>                                                                                                                                                                                                                                        |
| tripRecordingCanceled(state: DKTripRecordingCanceledState)                                                                                                                                                                                                                               | <p>Called when a trip recording is canceled. <code>DKTripRecordingCanceledState</code> indicates which event has canceled the trip.</p><p><code>DKTripRecordingCanceledState</code> object is described <a href="/pages/-LnH2v8JiN0ZC4OialHx#dktriprecordingcanceledstate">here</a>.</p>                                                                                                                                            |
| tripRecordingFinished(state: DKTripRecordingFinishedState)                                                                                                                                                                                                                               | <p>Called when trip recording has ended, before sending trip data to DriveQuant's servers.<br><code>DKTripRecordingFinishedState</code> object is described <a href="/pages/-LnH2v8JiN0ZC4OialHx#dktriprecordingfinishedstate">here</a>.</p>                                                                                                                                                                                        |
| tripFinished(responseStatus: TripResponseStatus)                                                                                                                                                                                                                                         | <p>This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.</p><p></p><p><a href="/pages/-LnH2v8JiN0ZC4OialHx#tripresponsestatus"><code>TripResponseStatus</code></a> object contains the trip analysis made on DriveQuant's server.</p>                                                                                                                                            |
| tripPoint(tripPoint: TripPoint)                                                                                                                                                                                                                                                          | Called when a trip is started and confirmed, for each GPS point recorded by the SDK. Data available in `TripPoint` object are described [here](/trip-analysis/ios/references#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()                                                                                                                                                                                                                                                                         | <p>Called when a beacon sets in the SDK is detected.<br>It is triggered exclusively if the trip recording has not been started yet (i.e. during the <code>INACTIVE</code> <a href="/pages/RQWwwTuNsEs1VslSzScZ#sdk-recorder-state">state</a>)</p>                                                                                                                                                                                   |
| beaconConfirmed(beacon: BeaconData)                                                                                                                                                                                                                                                      | <p>Called when a beacon set in the SDK is detected and confirmed during a trip.<br>It is triggered exclusively if the trip recording has started (i.e. during the <code>RUNNING</code> <a href="/pages/RQWwwTuNsEs1VslSzScZ#sdk-recorder-state">state</a>)</p>                                                                                                                                                                      |
| significantLocationChangeDetected()                                                                                                                                                                                                                                                      | Called when a user significant location change is detected.                                                                                                                                                                                                                                                                                                                                                                         |
| sdkStateChanged(state: State)                                                                                                                                                                                                                                                            | Called every time the state of the SDK changed with the new state as parameter. States are described [here](/trip-analysis/ios/tripmanagement#sdk-recorder-state).                                                                                                                                                                                                                                                                  |
| crashDetected(crashInfo: DKCrashInfo)                                                                                                                                                                                                                                                    | Called when a crash event is detected. Triggered if Crash Detection is enabled. Read more [here](https://docs.drivequant.com/trip-analysis/ios/crash-detection#enable-crash-detection)                                                                                                                                                                                                                                              |
| crashFeedbackSent(crashInfo: DKCrashInfo, feedbackType: DKCrashFeedbackType, severity: DKCrashFeedbackSeverity)                                                                                                                                                                          | called when crash feedback is enabled and a confirmed crash is detected. Triggered if Crash Detection is enabled. Read more [here](https://docs.drivequant.com/trip-analysis/ios/crash-detection#enable-crash-detection)                                                                                                                                                                                                            |
| <p><del>tripStarted(startMode: StartMode)</del><br><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripRecordingConfirmed(state: DKTripRecordingConfirmedState)</code></p>                     | Called each time a trip is started. `StartMode` indicates which event starts the trip. Possible values are described [here](/trip-analysis/ios/references#startmode).                                                                                                                                                                                                                                                               |
| <p><del>tripCancelled(cancelTrip: CancelTrip)</del><br><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripRecordingCanceled(state: DKTripRecordingCanceledState)</code></p>                   | Called when a trip is cancelled. `CancelTrip` indicates which event cancels the trip. Possible values are described [here](/trip-analysis/ios/references#canceltrip).                                                                                                                                                                                                                                                               |
| <p><del>tripFinished(post: PostGeneric, response: PostGenericResponse)</del></p><p><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripFinished(responseStatus: TripResponseStatus)</code></p> | <p>This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.</p><p></p><p><code>PostGeneric</code> object contains raw data sent to DriveQuant's server, <code>PostGenericResponse</code> object contains the trip analysis made on DriveQuant's server. Detailed description of these data are available <a href="/pages/-LmyNRA_muNPJIeFBcbX#response">here</a>.</p>               |

{% hint style="warning" %}
**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:&#x20;

* For a vehicle trip, you can display a message such as: `Your trip has been analyzed`.&#x20;
* For a trip by rail it is better to display the following message: `Your trip was made by train.`
  {% endhint %}

## Get the trip response status (Deprecated)

{% hint style="info" %}
This method has been deprecated and was [removed in DriveKit 3.0.0](/get-started-drivekit/ios/drivekit-3.0-migration-guide#method-replacements).

The callback method `tripFinished(post: PostGeneric, response: PostGenericResponse)` is replaced by `tripFinished(responseStatus: TripResponseStatus)` which directly provides the useful information (see [TripResponseStatus](/trip-analysis/ios/references#tripresponsestatus)).
{% endhint %}

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:

```swift
func getTripResponseStatus(_ tripResponse: PostGenericResponse) -> TripResponseStatus
```

The [TripResponseStatus](/trip-analysis/ios/references#tripresponsestatus) model is described in the References part.


# 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.&#x20;

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

This feature is enabled if the following conditions are fulfilled:

* Your API key has the access rights to use this service;&#x20;
* You have enabled the feature by following the instructions described in this section;&#x20;
* A trip has been detected and is being analysed.&#x20;
* The smartphone's sensors are functional.&#x20;
* 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.&#x20;
2. The crash feature detects a potential collision based on motion sensors.&#x20;
3. The GPS and motion data are pushed to the backend analysis services in charge of the signal processing and crash confirmation.&#x20;
4. The SDK receives a crash analysis service response with a status.&#x20;
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.&#x20;

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

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func activateCrashDetection(_ enable: Bool)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The crash detection comes with an optional user interface to display an alert to the driver. This is described in the [user interface](/trip-analysis/user-interface/ios/driver-alert-in-case-of-crash) section.
{% endhint %}

## 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
var isCrashDetectionAvailable: Bool
```

{% endtab %}
{% endtabs %}

This property returns `true` if:

* the required smartphone sensors are available and up and running;
* your API key is allowed to use the feature;

{% hint style="info" %}
If this property returns `false`, DriveKit will not start crash detection feature even if it has been previously activated with `activateCrashDetection()`.
{% endhint %}

## 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 use this function, you simply need to enable the interface with the following method and a [`DKCrashFeedbackConfig`](https://docs.drivequant.com/trip-analysis/ios/references#dkcrashfeedbackconfig) object:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func enableCrashFeedback(config: DKCrashFeedbackConfig)
```

{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```swift
func disableCrashFeedback()
```

{% endtab %}
{% endtabs %}

## Listening to Crash events

TripListener protocol provides two callbacks for crash events:

* `crashDetected(crashInfo:`[`DKCrashInfo`](https://docs.drivequant.com/trip-analysis/ios/references#dkcrashinfo)`)`, called when a crash event is detected
* `crashFeedbackSent(crashInfo:`[`DKCrashInfo`](https://docs.drivequant.com/trip-analysis/ios/references#dkcrashinfo)`, feedbackType:` [`DKCrashFeedbackType`](https://docs.drivequant.com/trip-analysis/ios/references#crashfeedbacktype)`, severity:`[`DKCrashFeedbackSeverity`](https://docs.drivequant.com/trip-analysis/ios/references#crashfeedbackseverity)`)`, called when crash feedback is enabled and a confirmed crash is detected. This callback will contain crash information and the feedback from the user.

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.


# 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.&#x20;

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

The DriveKit SDK is fully compatible with the [Apple iBeacon™](https://developer.apple.com/ibeacon/) standard.

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

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

A detailed description of `BeaconData` class is available [here](/trip-analysis/ios/references#beacondata).

{% hint style="info" %}
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)`
    {% endhint %}

{% hint style="danger" %}
Since iOS13, iOS beacon functions have some limitations, therefore all configured beacons must have the same proximity UUID.
{% endhint %}

{% hint style="info" %}
If you want to remove beacons from SDK configuration, just call the method with an empty array.
{% endhint %}

{% hint style="warning" %}
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.

*"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."*  [developer.apple.com](https://developer.apple.com/documentation/corelocation/monitoring_the_user_s_proximity_to_geographic_regions)
{% endhint %}

## 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:

```swift
DriveKitTripAnalysis.shared.setBeaconRequired(required: true)
```

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

```swift
DriveKitTripAnalysis.shared.setBeaconRequired(required: false)
```

{% hint style="info" %}
If you have configured the beacon and the [bluetooth device](/trip-analysis/ios/bluetooth-usage#bluetooth-device-required) as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.
{% endhint %}

## 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.

{% hint style="danger" %}
If this advanced configuration is not used correctly, it may result in poor trip detection performance.&#x20;

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

### 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:

```swift
DriveKitTripAnalysis.shared.allowBeaconTripStart = false
```

{% hint style="info" %}
This feature has no effect if the automatic trip detection mode is disabled.
{% endhint %}

## Beacon battery level

DriveKit is able to retrieve the battery level of a beacon and to add this information automatically in [trip's metadata](https://docs.drivequant.com/trip-analysis/ios/custom-metadata) (only for the current trip), so that you can know, for instance, if the beacon battery of a user needs to be changed.

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.

{% hint style="info" %}
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 [TripAnalysis auto start mode](https://docs.drivequant.com/trip-analysis/ios/auto-start).
{% endhint %}

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

<figure><img src="/files/hmgSzOjTWQ0YuCULcNcU" alt=""><figcaption></figcaption></figure>

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

```swift
DKDiagnosisHelper.shared.requestPermission(.bluetooth)
```

{% hint style="warning" %}
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.
  {% endhint %}


# 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:

```swift
let devices = DriveKitTripAnalysis.shared.getAvailableBluetoothDevices()
```

{% hint style="warning" %}
Bluetooth device will be seen only if the iPhone is connected to the vehicle bluetooth when this functions is called.
{% endhint %}

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

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

A detailed description of BluetoothData class is available [here](/trip-analysis/ios/references#bluetoothdata).

{% hint style="info" %}
If you want to remove Bluetooth devices from SDK configuration, just call the method with an empty array.
{% endhint %}

## 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:

```swift
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:

```swift
DriveKitTripAnalysis.shared.setBluetoothDeviceRequired(false)
```

{% hint style="info" %}
If you have configured the [beacon](/trip-analysis/ios/beacon-usage#beacon-required) and the bluetooth device as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.
{% endhint %}


# 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.

{% hint style="warning" %}
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 [`sdkStateChanged(state: State)`](/trip-analysis/ios/triplistener)callback, by checking if `state` is `inactive`.
{% endhint %}

## Set metadata

You can add additional metadata to your trip by calling the following method:

```swift
let metadata: [String: String] = [
    "key": "value"
]
DriveKitTripAnalysis.shared.setTripMetadata(metadata)
```

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:

```swift
DriveKitTripAnalysis.shared.getTripMetadata()
```

{% hint style="info" %}
Note: Any modification on the returned object has no effect on the metadata sent with a trip.
{% endhint %}

## Update metadata

To update a value in metadata, call the following method:

```swift
DriveKitTripAnalysis.shared.updateTripMetadata(key: String, value: String?)
```

## Delete a specific metadata

To delete a specific value in metadata, call the following method:

```swift
DriveKitTripAnalysis.shared.deleteTripMetadata(key: String)
```

## Delete all metadata

To delete all values in metadata, call this method:

```swift
DriveKitTripAnalysis.shared.deleteTripMetadata()
```


# 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:

```swift
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?
}
```

<table><thead><tr><th width="232">Attribute</th><th width="253">Type</th><th>Description</th></tr></thead><tbody><tr><td>status</td><td><code>TripResponseStatusType</code></td><td>Can be <code>tripValid</code> or <code>tripError.</code><br>- <code>tripValid</code> means that the analyzed trip is valid. <br>- <code>tripError</code> means that the trip has been analyzed but an error occurred and data is not valid.</td></tr><tr><td>itinId</td><td><code>String?</code></td><td>The id of the trip if <code>status</code> equals <code>tripValid</code>, otherwise <code>nil</code>.</td></tr><tr><td>localTripId</td><td><code>String?</code></td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object.</p></td></tr><tr><td>hasSafetyAndEcoDrivingScore</td><td><code>Bool</code></td><td>If <code>false</code>, it means that the trip is valid but too short to be analyzed.<br>In this case, there is no safety or eco-driving score.<br>It cannot be equals to <code>true</code> if status is not <code>tripValid</code>.</td></tr><tr><td>info</td><td><code>[</code><a href="#tripresponseinfo"><code>TripResponseInfo</code></a><code>]</code></td><td>If <code>status</code> equals <code>tripValid</code>, the DriveQuant servers returns a list of information codes. These are not errors.</td></tr><tr><td>error</td><td><a href="#tripresponseerror"><code>TripResponseError</code></a><code>?</code></td><td>If <code>status</code> equals <code>tripError</code>, error gives you more information about the error that occurred.</td></tr></tbody></table>

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

### TripResponseInfo

| Value                         | Description                                                                                                                                      |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| 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.                                                                                |

### TripResponseError

| Value                        | Description                                                                                                             |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| 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                                                             |

## DKTrip

<table><thead><tr><th width="261.66666666666663">Field</th><th width="351">Type</th><th>Description</th></tr></thead><tbody><tr><td>itinId</td><td><code>String</code></td><td>Trip unique identifier.</td></tr><tr><td>endDate</td><td><code>Date?</code></td><td>The end date of the trip.</td></tr><tr><td>startDate</td><td><code>Date?</code></td><td>The start date of the trip.</td></tr><tr><td>vehicleId</td><td><code>String?</code></td><td>The identifier of the vehicle used for this trip, if known.</td></tr><tr><td>transportationMode</td><td><code>TransportationMode</code></td><td>The transportation mode used for this trip, see <a href="/pages/-LnIYWt8LUcTbp4cVirZ#transportation-mode">Transportation Mode</a> for the description of the possible values.</td></tr><tr><td>declaredTransportationMode</td><td><code>DKDeclaredTransportationMode?</code></td><td>The transportation mode declared by the user. See <a href="#declaredtransportationmode">DeclaredTransportationMode</a>.</td></tr><tr><td>departureAddress</td><td><code>String?</code></td><td>The full address of the departure of the trip.</td></tr><tr><td>departureCity</td><td><code>String?</code></td><td>The city of the departure of the trip.</td></tr><tr><td>departurePostalCode</td><td><code>String?</code></td><td>The postal code of the trip departure.</td></tr><tr><td>departureState</td><td><code>String?</code></td><td>The state of the trip departure.</td></tr><tr><td>departureCountry</td><td><code>String?</code></td><td>The country of the trip departure.</td></tr><tr><td>arrivalAddress</td><td><code>String?</code></td><td>The full address of the arrival of the trip.</td></tr><tr><td>arrivalCity</td><td><code>String?</code></td><td>The city of the arrival of the trip.</td></tr><tr><td>arrivalPostalCode</td><td><code>String?</code></td><td>The postal code of the trip arrival.</td></tr><tr><td>arrivalState</td><td><code>String?</code></td><td>The state of the trip arrival.</td></tr><tr><td>arrivalCountry</td><td><code>String?</code></td><td>The country of the trip arrival.</td></tr><tr><td>unscored</td><td><code>Bool</code></td><td><code>true</code> if has no safety and eco-driving score.</td></tr><tr><td>occupantInfo</td><td><code>DKOccupantInfo?</code></td><td><p>Indicating whether the occupant was the driver or a passenger. </p><p>See <a href="#dkoccupantinfo">DKOccupantInfo</a></p></td></tr><tr><td>metadata</td><td><code>Dictionary&#x3C;String, String>?</code></td><td>Your specific data attached to the trip.  See <a href="/pages/RJhJdxQxqKzkamaSK2qZ">Custom metadata</a>.</td></tr><tr><td>tripStatistics</td><td><code>DKTripStatistics?</code></td><td>Indicators that characterize the trip conditions. See <a href="/pages/-LmyNRA_muNPJIeFBcbX#itinerarystatistics">ItineraryStatistics</a>.</td></tr><tr><td>brakeWear</td><td><code>DKBrakeWear?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">BrakeWear</a>.</td></tr><tr><td>tireWear</td><td><code>DKTireWear?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">TireWear</a>.</td></tr><tr><td>ecoDriving</td><td><code>DKEcoDriving?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#eco-driving">EcoDriving</a>.</td></tr><tr><td>ecoDrivingContexts</td><td><code>[DKEcoDrivingContext]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-eco-driving">AdvancedEcoDriving</a>.</td></tr><tr><td>fuelEstimation</td><td><code>DKFuelEstimation?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#fuel-estimation">FuelEstimation</a>.</td></tr><tr><td>fuelEstimationContexts</td><td><code>[DKFuelEstimationContext]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-fuel-estimation">Advanced fuel estimation</a>.</td></tr><tr><td>safety</td><td><code>DKSafety?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#safety">Safety</a>.</td></tr><tr><td>safetyContexts</td><td><code>[DKSafetyContext]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-safety">AdvancedSafety</a>.</td></tr><tr><td>safetyEvents</td><td><code>[DKSafetyEvents]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#safetyevents">SafetyEvents</a>.</td></tr><tr><td>driverDistraction</td><td><code>DKDriverDistraction?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#driver-distraction-score">DriverDistraction</a>.</td></tr><tr><td>pollutants</td><td><code>DKPollutants?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#pollutants">Pollutants</a>.</td></tr><tr><td>speedingStatistics</td><td><code>DKSpeedingStatistics?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#speed-limit">Speed Limit</a>.</td></tr><tr><td>speedLimitContexts</td><td><code>[DKSpeedLimitContext]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#speedlimitcontexts">SpeedLimitContexts</a>.</td></tr><tr><td>calls</td><td><code>[DKCall]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#call">CallEvent</a>.</td></tr><tr><td>energyEstimation</td><td><code>DKEnergyEstimation?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#energyestimation">EnergyEstimation</a>.</td></tr><tr><td>advancedEnergyEstimation</td><td><code>[DKAdvancedEnergyEstimation]?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advancedenergyestimation">AdvancedEnergyEstimation</a>.</td></tr></tbody></table>

### DKOccupantInfo

<table><thead><tr><th width="188">Field</th><th width="159">Type</th><th>Description</th></tr></thead><tbody><tr><td>role</td><td><code>DKOccupantRole</code></td><td><p>Indicates the role of the occupant.</p><p>See <a href="#dkoccupantrole">DKOccupantRole</a>.</p></td></tr><tr><td>passengerProbability</td><td>Int</td><td>Probability, expressed as a percentage, that the vehicle occupant is a passenger.</td></tr></tbody></table>

### DKOccupantRole

<table><thead><tr><th width="206">Value</th><th>Description</th></tr></thead><tbody><tr><td>driver</td><td>The vehicle occupant is very likely to be a driver.</td></tr><tr><td>passenger</td><td>The vehicle occupant is very likely to be a passenger.</td></tr><tr><td>unavailable</td><td>The trip data and historical information about the user's habits do not allow determining whether the occupant is a driver or a passenger. In this case, we recommend considering the occupant as the driver for this trip.</td></tr><tr><td>notApplicable</td><td>The trip was made using public transportation (such as train or bus) or by a mode of transport other than a car (e.g., bicycle, boat, plane). In these cases, driver/passenger detection is not performed.</td></tr></tbody></table>

### 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:

<table><thead><tr><th width="197">Field</th><th width="214">Type</th><th>Description</th></tr></thead><tbody><tr><td>transportationMode</td><td>TransportationMode</td><td>The transportation mode declared by the user for this trip. See <a href="/pages/-LnIYWt8LUcTbp4cVirZ#transportation-mode">Transportation Mode</a> for the description of the possible values.</td></tr><tr><td>passenger</td><td><code>Boolean?</code></td><td><code>true</code> if the trip was made as a passenger, <code>false</code> if the trip was made as the driver.</td></tr><tr><td>comment</td><td><code>String?</code></td><td>The comment associated to this declaration.</td></tr></tbody></table>

## DKTripRecordingStartedState

This object is returned in the [`TripListener`](/trip-analysis/ios/triplistener)'s `tripRecordingStarted()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresponsestatus">TripResponseStatus</a> after DriveQuant platform's analysis.</td></tr></tbody></table>

## DKTripRecordingConfirmedState

This object is returned in the [`TripListener`](/trip-analysis/ios/triplistener)'s `tripRecordingConfirmed()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresponsestatus">TripResponseStatus</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date</td><td>Date when the trip entered into the confirmation state.</td></tr></tbody></table>

## DKTripRecordingCanceledState

This object is returned in the [`TripListener`](/trip-analysis/ios/triplistener)'s `tripRecordingCanceled()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresponsestatus">TripResponseStatus</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date?</td><td>Date when the trip was confirmed if the trip entered into the confirmation state.</td></tr><tr><td>cancelationReason</td><td>DKTripCancelationReason</td><td><p>Indicates how the trip was canceled.</p><p>Possible values are described <a href="#dktripcancelationreason">here</a>.</p></td></tr></tbody></table>

## DKTripRecordingFinishedState

This object is returned in the [`TripListener`](/trip-analysis/ios/triplistener)'s `tripRecordingFinished()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresponsestatus">TripResponseStatus</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date</td><td>Date when the trip was confirmed if the trip entered into the confirmation state.</td></tr><tr><td>recordingEndDate</td><td>Date</td><td>Date when DriveKit has terminated the trip recording.<br>⚠️  It is not the trip end date returned in <a href="#tripresponsestatus">TripResponseStatus</a> after DriveQuant platform's analysis..</td></tr></tbody></table>

## StartMode

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

| Value              | Description                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ |
| gps                | Automatic start when the SDK detects a change in user's position                                                   |
| beacon             | Automatic start due to the presence of a beacon                                                                    |
| manual             | Trip started manually by calling the method [`startTrip`](/trip-analysis/ios/tripmanagement#manually-start-a-trip) |
| 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                                 |

## DKTripCancelationReason

| Value                  | Description                                                                                                                                                                                                                                                        |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| user                   | Trip canceled by calling the method [`cancelTrip`](/trip-analysis/ios/tripmanagement#cancel-a-trip)                                                                                                                                                                |
| 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               | Trip canceled because the beacon was not detected while it was [required](/trip-analysis/ios/beacon-usage#beacon-required)                                                                                                                                         |
| noBluetoothDevice      | Trip canceled because the Bluetooth device was not detected while it was [required](/trip-analysis/ios/bluetooth-usage#bluetooth-device-required).                                                                                                                 |
| missingConfiguration   | Trip canceled because DriveKit was not configured                                                                                                                                                                                                                  |
| noLocationData         | Trip canceled because no location data was recorded                                                                                                                                                                                                                |
| reset                  | Trip canceled because SDK configuration has been [reset](/get-started-drivekit/ios/advanced-configurations#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              | <p>The trip recording has been canceled due to an app termination.<br>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.</p> |

## 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.

```swift
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
}
```

| Attribute            | Type   | Description                                                                                                                                                                                              | Default value, if not specified |
| -------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| carTypeIndex         | Int    | [Vehicle body type](/trip-analysis/rest-services/references#vehicle-body-type)                                                                                                                           | 1                               |
| carEngineIndex       | Int    | [Engine type](/trip-analysis/rest-services/references#engine-type)                                                                                                                                       | 1                               |
| carPower             | Double | 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.7355$$ (min: 40 hp, max 450 hp) | 150                             |
| carMass              | Double | Vehicle mass in kg (min: 700 kg, max: 3500 kg)                                                                                                                                                           | 1400                            |
| carGearboxIndex      | Int    | [Gearbox type](/trip-analysis/rest-services/references#gearbox-type)                                                                                                                                     | 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    | [​Drive wheels type​](https://docs.drivequant.com/trip-analysis/rest-services/references#drive-wheels-type)                                                                                              | 0                               |
| engineCylinderNb     | Int    | Number of cylinders                                                                                                                                                                                      | 4                               |

## BeaconData

BeaconData is an object that contains beacon characteristics.

| Attribute     | Type   | Description                   |
| ------------- | ------ | ----------------------------- |
| proximityUuid | String | Beacon proximity UUID         |
| major         | Int    | Beacon major value (optional) |
| minor         | Int    | Beacon minor value (optional) |

## 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:

```swift
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?
}
```

with the following enumeration for crash status

```swift
public enum DKCrashStatus {
    case unconfirmed
    case confirmed
}
```

| Attribute       | Type            | Description                                                                                                                                                                                                              |
| --------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| crashId         | String          | Crash unique identifier                                                                                                                                                                                                  |
| date            | Date            | <p>Crash date </p><p>Example: <code>2023-03-07T09:13:22.461+0200</code></p>                                                                                                                                              |
| 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?         | <p>When a crash is confirmed and <a href="/pages/leo4dxpUiyoESHjb6FH0">push crash data</a> is activated, an URL of the map that will display the location data is returned.</p><p>Otherwise, it is <code>nil</code>.</p> |

## DKCrashFeedbackConfig

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

| Attribute              | Type                        | Description                                                                                                                                                                                                                                       |
| ---------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| notification           | DKCrashFeedbackNotification | Configuration of the notification                                                                                                                                                                                                                 |
| crashVelocityThreshold | Double                      | <p>Minimal speed when the crash occurred.</p><p>For example, if <code>crashVelocityThreshold</code> is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user. </p><p><strong>Default value</strong>: 0.0 km/h</p> |

## DKCrashFeedbackNotification

| Attribute  | Type         | Description                                                                                                                                       |
| ---------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| title      | String       | Title that appears on the notification                                                                                                            |
| message    | String       | Message that appears on the notification                                                                                                          |
| crashAlert | DKCrashAlert | <p>Enum value that describes how the user will be noticed when a feedback is asked</p><p><strong>Default value</strong>: <code>silence</code></p> |

## DKCrashAlert

| Enum value        | Description                      |
| ----------------- | -------------------------------- |
| silence           | Device will not vibrate nor ring |
| vibration         | Device will vibrate              |
| soundAndVibration | Device will ring and vibrate     |

## CrashFeedbackType

| Enum value | Description                       |
| ---------- | --------------------------------- |
| noCrash    | User said that no crash occurred  |
| confirmed  | User confirmed a crash            |
| noFeedback | 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  |

### DKTripLocation

<table data-full-width="false"><thead><tr><th>Property/Method</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td>Date</td><td>Date of the end of trip.</td></tr><tr><td>latitude</td><td>Double</td><td>Latitude of the end of the trip.</td></tr><tr><td>longitude</td><td>Double</td><td>Longitude of the end of the trip.</td></tr><tr><td>accuracyMeter</td><td>Double</td><td>GPS data accuracy value in meters.</td></tr><tr><td>func getAccuracyLevel()</td><td>DKCoordinateAccuracy</td><td>GPS data accuracy level. Possible values are described below.</td></tr></tbody></table>

### 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. |

## CancelTrip (Deprecated)

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

<table><thead><tr><th width="343">Value</th><th>Description</th></tr></thead><tbody><tr><td>user</td><td>Trip cancelled by calling the method <a href="/pages/RQWwwTuNsEs1VslSzScZ#cancel-a-trip"><code>cancelTrip</code></a></td></tr><tr><td>highspeed</td><td>Trip cancelled because speed was too high (train, airplane)</td></tr><tr><td>noSpeed</td><td>Trip cancelled because speed was too slow to be in a vehicle</td></tr><tr><td>noBeacon</td><td>Trip cancelled because the beacon was not detected while it was  <a href="/pages/-LmyMCOElL-ypTu0lqSn#beacon-required">required</a></td></tr><tr><td>missingConfiguration</td><td>Trip cancelled because DriveKit was not configured</td></tr><tr><td>noGPSData</td><td>Trip cancelled because no GPS data was recorded</td></tr><tr><td>reset</td><td>Trip cancelled because SDK configuration has been <a href="/pages/9BMigmEn4pkOj3P13cNN#reset-the-module">reset</a></td></tr><tr><td>beaconNoSpeed</td><td>Trip cancelled because the beacon is near the smartphone but there is no movement (zero or low speed)</td></tr><tr><td>bluetoothDeviceNoSpeed</td><td>Trip cancelled because the Bluetooth device is connected to the smartphone but there was no movement (zero or low speed)</td></tr></tbody></table>


# Android


# Runtime permissions

## Location Permission

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

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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)
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
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);
            }
        }
    }

```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
If location permission is not granted by the user, Trip Analysis SDK will not work.
{% endhint %}

## 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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)
}
```

{% endtab %}

{% tab title="Java" %}

```java
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)
}
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
If activity recognition permission is not granted by the user, Trip Analysis component will not work.
{% endhint %}

## 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.

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 [this topic](https://developer.android.com/training/monitoring-device-state/doze-standby.html#whitelisting-cases).

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

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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)
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
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);
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
If battery optimization is enabled, trip recording will not work.
{% endhint %}

{% hint style="warning" %}
Some manufacturers add other battery optimizations. You can find tutorials on how to disable these battery optimizations for main Android device manufacturers [here](https://info.drivequant.com/smartphone-configuration).
{% endhint %}

## Nearby Devices Permission

For devices running Android 12 and above, it's required to ask the user for [Nearby Devices permission](https://developer.android.com/guide/topics/connectivity/bluetooth/permissions). Find below an example of how to ask Nearby Devices permission:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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)
        }        
    }
}

```

{% endtab %}

{% tab title="Java" %}

```java
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);
        }
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
If Nearby Devices permission is not granted by the user, Trip Analysis component won't work correctly.
{% endhint %}

## Notification Runtime Permission

For devices running Android 13 and above, it's required to ask the user for [Notification runtime permission](https://developer.android.com/develop/ui/views/notifications/notification-permission). If the permission is not granted, the user will not receive notifications.

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

First, declare the permission in your Manifest app file:

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

```

Then request the permission on your UI:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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)
            }
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
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);
            }
        }
    }
}
```

{% endtab %}
{% endtabs %}

## Full-screen intent permission

For Android 14 devices and above, it is now necessary to ask the user for this permission to display full screen notification for the [Crash Detection feedback](/trip-analysis/android/crash-detection#configure-crash-detection-feedback) feature.

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:

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

```

Then request the permission on your UI:

{% tabs %}
{% tab title="Kotlin" %}

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

{% endtab %}

{% tab title="Java" %}

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

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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()
        }
    }
}
```

{% endtab %}
{% endtabs %}


# Trip management

## Configure the trip notification content

There are two methods to configure the trip recording notification:&#x20;

* The first method uses the `TripNotification` object, which does not involve any Android-specific notification logic.
* The second method uses the `DKNotification` object, which allows you to pass Android objects such as `NotificationChannel` and `Notification`, directly to DriveKit. This allows configuring how the notification is displayed in your application.

{% hint style="warning" %}

* In both cases, the method must be called in the `onCreate()` of your *Application* class.
* If the app calls both methods, the one using the `DKNotification` object will be taken into account and the one using the `TripNotification` object will be ignored.
* The DriveKit SDK automatically creates the notification channel with the provided information.
  {% endhint %}

### With the TripNotification object

`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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
val notification = TripNotification(
    title = "Trip notification title",
    content = "Trip notification content",
    iconId = R.drawable.ic_notification
)
DriveKitTripAnalysis.tripNotification = notification
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th>Attribute</th><th width="220.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>title</td><td>String</td><td>Title of the notification</td></tr><tr><td>content</td><td>String</td><td>Content of the notification</td></tr><tr><td>iconId</td><td>Int</td><td>The icon Android resource identifier for notification</td></tr><tr><td>channelName</td><td>String</td><td><p>Name of the Android notification channel which is displayed in the app's notification settings.</p><p>If not set, the channel name takes the value of <code>title</code> attribute</p></td></tr><tr><td>channelId</td><td>String</td><td>Identifier of the Android notification channel used. The default value is <code>dq_sdk_channel</code></td></tr><tr><td>notificationId</td><td>Int?</td><td>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.</td></tr><tr><td>contentIntent</td><td>PendingIntent?</td><td>The Intent which will be launched when the user taps on the notification. Default value is <code>null</code>.</td></tr><tr><td>enableCancel</td><td>Boolean</td><td>If <code>true</code>, a cancel button will be displayed in notification that cancels the trip when pressed.<br>Default value is <code>false</code>.</td></tr><tr><td>cancel</td><td>String?</td><td>Text of the cancel button.<br>Default value is <code>null</code>.</td></tr><tr><td>cancelIconId</td><td>Int?</td><td>Icon resource of the cancel button.<br>Default value is <code>null</code>.</td></tr></tbody></table>

{% hint style="warning" %}
The **cancelIconId** and **cancel** parameters must be set if the **enableCancel** parameter is set to true.
{% endhint %}

### With the DKNotification object

This method allows the app to dynamically configure the trip notification by using Android's [NotificationChannel](https://developer.android.com/reference/android/app/NotificationChannel) and [Notification](https://developer.android.com/reference/android/app/Notification) objects.

Each time the trip recording starts, the SDK will invoke the lambda method and use the `DKNotification` provided by the app.

#### DKNotification

<table><thead><tr><th width="154">Field</th><th width="179">Type</th><th>Description</th></tr></thead><tbody><tr><td>channel</td><td><a href="https://developer.android.com/reference/android/app/NotificationChannel">NotificationChannel</a></td><td>Channel where the notification associated with the trip recording foreground service.</td></tr><tr><td>notificationId</td><td>Int</td><td><p>Id of the trip notification.</p><p>Must <strong>not</strong> be <code>0</code>, according to the Android documentation.<br>If the id is set as 0, DriveKit will generate a random integer from <code>1</code> until <code>Integer.MAX_VALUE</code>.</p><p>Plus, a DriveKitLog error entry is written.</p></td></tr><tr><td>notification</td><td><a href="https://developer.android.com/reference/android/app/Notification">Notification</a></td><td>Data of the notification.</td></tr></tbody></table>

{% hint style="info" %}
If the `DKNotification` is `null`, the SDK will use the `tripNotification` object.
{% endhint %}

To configure the trip notification in your app with the `configureNotification()` method, call the following code:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val notificationId = 123
val title = "Notification title"
val content = "Notification content"
val channelId = "yourChannelId"
val channelName = "yourChannelName"
DriveKitTripAnalysis.configureNotification {
    val builder = NotificationCompat.Builder(this, channelId)
        .setSmallIcon(R.drawable.ic_trip_recording)
        .setStyle(NotificationCompat.BigTextStyle().bigText(content))
        .setContentTitle(title)
        .setContentText(content)
    val notification = builder.build()
    val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
    DKNotification(channel, notificationId, notification)
}
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitTripAnalysis.configureNotification(() -> {
    final int notificationId = 123;
    final String channelId = "yourChannelId";
    final String channelName = "youChannelName";
    final NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
    final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(application, channelId);
    notificationBuilder.setContentTitle("Notification title");
    notificationBuilder.setContentText("Notification content");
    notificationBuilder.setSmallIcon(R.drawable.ic_trip_recording);
    return new DKNotification(channel, notificationId, notificationBuilder.build());
});
```

{% endtab %}
{% endtabs %}

## 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`.

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun activateAutoStart(activate: Boolean)
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
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 [`cancelTrip`](#cancel-a-trip) method.
{% endhint %}

### Manually start a trip

You can start a trip by calling the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun startTrip()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If a trip is already started, calling this method will have no effect.
{% endhint %}

### Stop a trip

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun stopTrip()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If a vehicle stops longer than the timeout[^1] configured, the trip will be stopped automatically.
{% endhint %}

{% hint style="info" %}
If no trip is running, calling this method will have no effect.
{% endhint %}

### Cancel a trip

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun cancelTrip()
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setVehicle(vehicle: TripVehicle)
```

{% endtab %}
{% endtabs %}

A detailed description of vehicle parameter is available [here](/trip-analysis/android/references#tripvehicle).

{% hint style="info" %}
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`
  {% endhint %}

## SDK recorder state

Two methods are available to determine SDK state.

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun isTripRunning(): Boolean
```

{% endtab %}
{% endtabs %}

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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getRecorderState(): State
```

{% endtab %}
{% endtabs %}

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](#custom-stop-timeout) 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 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.

{% hint style="info" %}

* 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`).
  {% endhint %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getCurrentTripInfo(): DKTripInfo?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The method can return `null` if there is no trip currently recording.
{% endhint %}

### DKTripInfo

| Property    | Type        | Description                                                                                                                                                                                                                                                     |
| ----------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| localTripId | `String`    | <p>Local and unique trip identifier generated by DriveKit SDK.</p><p>⚠️ It is different from the <code>itinId</code> property returned in the Trip object. <code>itinId</code> corresponds to the unique trip identifier generated after the data analysis.</p> |
| date        | `Date`      | <p>Start date of the trip recording. </p><p>⚠️ It is different from the startDate property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object.</p>                                                                                      |
| startMode   | `StartMode` | The [StartMode](/trip-analysis/android/references#startmode) which triggered the trip recording.                                                                                                                                                                |

## 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.&#x20;

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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun checkTripToRepost()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.
{% endhint %}

{% hint style="warning" %}
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.
{% endhint %}

## Custom stop timeout <a href="#custom-stop-timeout" id="custom-stop-timeout"></a>

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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setStopTimeOut(timeOut: Int)
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
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.
{% endhint %}

## Custom max speed before cancellation

A trip being recorded is automatically cancelled if the speed is above a given value. The DriveKit SDK allows you to modify the threshold.

By default, the trip recording is canceled with the [HIGH\_SPEED](/trip-analysis/android/references#dktripcancelationreason) trip cancellation reason when speed is above 200 km/h. This value can be tuned according to your need and you can choose any Double values between 50 and 1500 km/h by calling the following code:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val desiredMaxSpeed = 300.0 // in km/h
DriveKitTripAnalysis.autoCancelTripMaxSpeed = desiredMaxSpeed
```

{% endtab %}

{% tab title="Java" %}

```java
double desiredMaxSpeed = 300.0; // in km/h
DriveKitTripAnalysis.INSTANCE.setAutoCancelTripMaxSpeed(desiredMaxSpeed);
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If a value greater than 1500 is set, the value will be forced to 1500.

If a value lower than 50 is set, the value will be forced to 50.
{% endhint %}

## 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitTripAnalysis.tripSharing.isAvailable()
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitTripAnalysis.getTripSharing().isAvailable()
```

{% endtab %}
{% endtabs %}

### Create a link

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

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val oneHourInSeconds = 3600
DriveKitTripAnalysis.tripSharing.createLink(oneHourInSeconds) { status: CreateTripSharingLinkStatus, data: DKTripSharingLink? ->
    // Check the status and manage the data
}
```

{% endtab %}

{% tab title="Java" %}

```java
int oneHourInSeconds = 3600;
DriveKitTripAnalysis.getTripSharing().createLink(oneHourInSeconds, (CreateTripSharingLinkStatus status, DKTripSharingLink data) -> {
    // Check the status and manage the data
    return null;
});
```

{% endtab %}
{% endtabs %}

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

#### CreateTripSharingLinkStatus

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>SUCCESS</td><td>The link has been successfully created. Information is returned in <code>data</code>.</td></tr><tr><td>ACTIVE_LINK_ALREADY_EXISTS</td><td><p>A link already exists for this user.</p><p>Information returned in <code>data</code> is null.</p><p></p><p>💡 You have to call the method to <a href="#retrieve-a-valid-sharing-link">retrieve an existing link</a> in your workflow.</p></td></tr><tr><td>ERROR</td><td><p>An error occurred, for instance when the user has no network.</p><p>Information returned in <code>data</code> is null.</p></td></tr><tr><td>USER_NOT_CONNECTED</td><td>The user is not yet connected to DriveKit. Information returned in <code>data</code> is null.</td></tr><tr><td>INVALID_DURATION</td><td>An error occurred when trying to create a link. The duration parameter must be strictly greater than 0. Information returned in <code>data</code> is null.</td></tr><tr><td>UNAUTHENTICATED</td><td><p>The user has been disconnected.</p><p>Information returned in <code>data</code> is null.</p></td></tr><tr><td>FORBIDDEN</td><td><p>Your API key is <strong>not</strong> allowed to use the feature.</p><p>Information returned in <code>data</code> is null.</p></td></tr></tbody></table>

#### 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitTripAnalysis.tripSharing.getLink(SynchronizationType.DEFAULT) { status, data ->
    // Check the status and manage the data
}
```

{% endtab %}

{% tab title="Java" %}

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

{% endtab %}
{% endtabs %}

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

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>SUCCESS</td><td>The link has been successfully retrieved. Information is returned in <code>data</code>.</td></tr><tr><td>FAILED_TO_GET_CACHE_ONLY</td><td>An error occurred when trying to retrieve a link. Locally trip sharing link, if exists, is returned in data.</td></tr><tr><td>NO_ACTIVE_LINK</td><td><p>There is no active link for the user.</p><p>Information returned in <code>data</code> is null.</p></td></tr><tr><td>USER_NOT_CONNECTED</td><td>The user is not yet connected to DriveKit. Information returned in <code>data</code> is null.</td></tr><tr><td>UNAUTHENTICATED</td><td><p>The user has been disconnected.</p><p>Information returned in <code>data</code> is null.</p></td></tr><tr><td>FORBIDDEN</td><td><p>Your API key is <strong>not</strong> allowed to use the feature.</p><p>Information returned in <code>data</code> is null.</p></td></tr></tbody></table>

### Revoke a trip sharing link

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

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitTripAnalysis.tripSharing.revokeLink { status ->
    // Check the status and manage
}
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitTripAnalysis.getTripSharing().revokeLink((RevokeTripSharingLinkStatus status) -> {
    // Check the status
    return null;
});
```

{% endtab %}
{% endtabs %}

#### RevokeTripSharingLinkStatus

<table><thead><tr><th width="303">Value</th><th>Description</th></tr></thead><tbody><tr><td>SUCCESS</td><td>The link has been successfully revoked.</td></tr><tr><td>NO_ACTIVE_LINK</td><td>There is no active link for the user.</td></tr><tr><td>ERROR</td><td>An error occurred when trying to revoke the link.</td></tr><tr><td>USER_NOT_CONNECTED</td><td>The user is not yet connected to DriveKit.</td></tr><tr><td>UNAUTHENTICATED</td><td>The user has been disconnected.</td></tr><tr><td>FORBIDDEN</td><td>Your API key is <strong>not</strong> allowed to use the feature.</td></tr></tbody></table>

## Sharing data during the trip

{% hint style="warning" %}
This feature allows you to share to the server the location of a driver during all his trips. It is different from the [trip sharing with a link](#share-trips-with-a-link) feature where the user chooses to share his trips for a certain duration, thanks to a link showing his current trip on a map.
{% endhint %}

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`:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun enableSharePosition(enable: Boolean)
```

{% endtab %}
{% endtabs %}

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.

{% hint style="info" %}
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.
{% endhint %}

## 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
var monitorPotentialTripStart: Boolean
```

{% endtab %}
{% endtabs %}

Once the feature is enabled, events will be available in the [TripListener](/trip-analysis/android/triplistener) `potentialTripStart()` callback.

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.&#x20;

The returned location type is [DKTripLocation](/trip-analysis/android/references#dktriplocation)

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

{% hint style="info" %}
The last trip corresponds to the last trip recorded by the DriveKit SDK, regardless of the mode of transport used.
{% endhint %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getLastTripLocation(): DKTripLocation?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.
  {% endhint %}

### Get Last Vehicle Trip Location

This function returns the location of the end of the last vehicle trip.&#x20;

The returned location type is [DKTripLocation](/trip-analysis/android/references#dktriplocation)

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getLastVehicleTripLocation(): DKTripLocation?
```

{% endtab %}
{% endtabs %}

## StartMode of the current trip

{% hint style="warning" %}
**This method is now deprecated.**

It is now possible to retrieve the start mode of the current trip using the `getCurrentTripInfo()` method.
{% endhint %}

Trip Analysis offers a method to retrieve the [`StartMode`](/trip-analysis/android/references#startmode) of the current trip. The method returns `null` if no trip is running.

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getCurrentStartMode(): StartMode?
```

{% endtab %}
{% endtabs %}

##

[^1]: timeout


# 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.

All `TripListener` callbacks are guaranteed to be triggered on the main thread.

{% hint style="info" %}
The trip recording lifecycle is exhaustively described in [Trip recording lifecycle](/get-started-drivekit/trip-recording-lifecycle) part.
{% endhint %}

## Add a TripListener

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun addTripListener(listener: TripListener)
```

{% endtab %}
{% endtabs %}

You can remove a specific listener using the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun removeTripListener(listener: TripListener)
```

{% endtab %}
{% endtabs %}

To remove all TripListeners objects:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun removeAllTripListeners()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.).
{% endhint %}

{% hint style="warning" %}
Do not forget to remove your `TripListener` objects when you don't need it anymore to prevent memory leaks.
{% endhint %}

`TripListener` interface includes several methods to implement:

<table data-full-width="false"><thead><tr><th width="314">Method</th><th>Description</th></tr></thead><tbody><tr><td>tripRecordingStarted(state: DKTripRecordingStartedState)</td><td><p>Immediately called when a trip recording starts.</p><p>This callback is triggered:</p><ul><li>after calling the DriveKit SDK's <a href="/pages/SUydR5jFmApf1N6yBA6O#manually-start-a-trip"><code>startTrip()</code></a> method.</li><li>after automatic trip detection.</li></ul><p><code>DKTripRecordingStartedState</code> object is described <a href="/pages/-LnMH5ErH5WNrLs46vVd#dktriprecordingstartedstate">here</a>.</p></td></tr><tr><td>tripRecordingConfirmed(state: DKTripRecordingConfirmedState)</td><td>Called each time a trip is confirmed.<br><code>DKTripRecordingConfirmedState</code> object is described <a href="/pages/-LnMH5ErH5WNrLs46vVd#dktriprecordingconfirmedstate">here</a>.</td></tr><tr><td>tripRecordingCanceled(state: DKTripRecordingCanceledState)</td><td><p>Called when a trip recording is canceled. <code>DKTripRecordingCanceledState</code> indicates which event has canceled the trip.</p><p><code>DKTripRecordingCanceledState</code> object is described <a href="/pages/-LnMH5ErH5WNrLs46vVd#dktriprecordingcanceledstate">here</a>.</p></td></tr><tr><td>tripRecordingFinished(state: DKTripRecordingFinishedState)</td><td>Called when trip recording has ended, before sending trip data to DriveQuant's servers.<br><code>DKTripRecordingFinishedState</code> object is described <a href="/pages/-LnMH5ErH5WNrLs46vVd#dktriprecordingfinishedstate">here</a>.</td></tr><tr><td>tripFinished(result: TripResult)</td><td><p>This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.<br></p><p><a href="/pages/-LnMH5ErH5WNrLs46vVd#tripresult"><code>TripResult</code></a> object contains the trip analysis result made on DriveQuant's server.</p></td></tr><tr><td>tripPoint(tripPoint: TripPoint)</td><td>Called when a trip is started and confirmed, for each location point recorded  by the SDK. Data available in <code>TripPoint</code> object are described <a href="/pages/-LnMH5ErH5WNrLs46vVd#trippoint">here</a>.</td></tr><tr><td>tripSavedForRepost()</td><td>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.</td></tr><tr><td>beaconDetected()</td><td>This method is called when a beacon set in the SDK is detected.<br>It is triggered exclusively if the trip recording has not been started yet (i.e. during the <code>INACTIVE</code> <a href="/pages/SUydR5jFmApf1N6yBA6O#sdk-recorder-state">state</a>)</td></tr><tr><td>beaconConfirmed(beacon: BeaconData)</td><td>Called when a beacon set in the SDK is detected and confirmed during a trip.<br>It is triggered exclusively if the trip recording has started (i.e. during the <code>RUNNING</code> <a href="/pages/SUydR5jFmApf1N6yBA6O#sdk-recorder-state">state</a>)</td></tr><tr><td>sdkStateChanged(state: State)</td><td>This method is called every time the state of the SDK changed with the new state as parameter. States are described <a href="/pages/SUydR5jFmApf1N6yBA6O#sdk-recorder-state">here</a>. </td></tr><tr><td>crashDetected(crashInfo: DKCrashInfo)</td><td>Called when a crash event is detected. Triggered if crash detection is enabled. Read more <a href="https://docs.drivequant.com/trip-analysis/android/crash-detection#enable-crash-detection">here</a></td></tr><tr><td>crashFeedbackSent(crashInfo: DKCrashInfo, feedbackType: DKCrashFeedbackType, severity: DKCrashFeedbackSeverity)</td><td>Called when crash feedback is enabled and a confirmed crash is detected. Triggered if Crash Detection is enabled. Read more <a href="https://docs.drivequant.com/trip-analysis/android/crash-detection#enable-crash-detection">here</a></td></tr><tr><td><del>tripStarted(startMode: StartMode)</del><br><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripRecordingConfirmed(state: DKTripRecordingConfirmedState)</code></td><td><p>Called each time a trip has started and is confirmed. <code>StartMode</code> indicates which event starts the trip.</p><p>Possible values are described <a href="/pages/-LnMH5ErH5WNrLs46vVd#startmode">here</a>.</p></td></tr><tr><td><del>tripCancelled(cancelTrip: CancelTrip)</del><br><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripRecordingCanceled(state: DKTripRecordingCanceledState)</code></td><td>This method is called when a trip is cancelled. CancelTrip indicates which event cancels the trip. Possible values are described <a href="https://docs.drivequant.com/trip-analysis/ios/references#canceltrip">here</a>.</td></tr><tr><td><p><del>tripFinished(post: PostGeneric, response: PostGenericResponse)</del></p><p><span data-gb-custom-inline data-tag="emoji" data-code="26a0">⚠️</span> <em>This method has been deprecated to be replaced by:</em> <code>tripFinished(result: TripResult)</code></p></td><td><p>This method is called when a trip has been recorded by the SDK and analyzed by the DriveQuant's servers.<br></p><p><code>PostGeneric</code> contains raw data sent to DriveQuant's server, <code>PostGenericResponse</code> object contains the trip analysis made on DriveQuant's server.</p><p>Detailed description of these data are available <a href="/pages/-LmyNRA_muNPJIeFBcbX#response">here</a>.</p></td></tr><tr><td><del>onDeviceConfigEvent(deviceConfigEvent: DeviceConfigEvent)</del></td><td>This method is deprecated and was <a href="/pages/Hwhsym9YVzxaroqOdKwc#triplistener-interface-updated-methods-and-types">removed in DriveKit 3.0.0</a>. It is replaced by the <code>DKDeviceConfigurationListener</code>. Read more <a href="/pages/kWvK0sz843cs0hEu9ZNH#listen-for-permissions-and-sensors-status-changes">here</a>.</td></tr></tbody></table>

{% hint style="warning" %}
**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:&#x20;

* For a vehicle trip, you can display a message such as: `Your trip has been analyzed`.&#x20;
* For a trip by rail it is better to display the following message: `Your trip was made by train.`
  {% endhint %}

## Get the trip response status (Deprecated)

{% hint style="info" %}
This method has been deprecated and was [removed in DriveKit 3.0.0](/get-started-drivekit/android/drivekit-3.0-migration-guide#method-replacements).

The callback method `tripFinished(post: PostGeneric, response: PostGenericResponse)` is replaced by `tripFinished(result: TripResult)` which directly provides the useful information (see [TripResult](/trip-analysis/android/references#tripresult)).
{% endhint %}

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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getTripResponseStatus(tripResponse: PostGenericResponse): TripResponseStatus
```

{% endtab %}
{% endtabs %}

The [TripResponseStatus](/trip-analysis/android/references#tripresponsestatus-deprecated) model is described in the References part.


# 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.&#x20;

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

This feature is enabled if the following conditions are fulfilled:

* Your API key has the access rights to use this service;&#x20;
* You have enabled the feature by following the instructions described in this section;&#x20;
* A trip has been detected and is being analysed.&#x20;
* The smartphone's sensors are functional.&#x20;
* 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.&#x20;
2. The crash feature detects a potential collision based on motion sensors.&#x20;
3. The GPS and motion data are pushed to the backend analysis services in charge of the signal processing and crash confirmation.&#x20;
4. The SDK receives a crash analysis service response with a status.&#x20;
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.&#x20;

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

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun activateCrashDetection(activate: Boolean)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The crash detection comes with an optional feature to display an alert to the driver. This is described in the [user interface](/trip-analysis/user-interface/android/driver-alert-in-case-of-crash) section.
{% endhint %}

## 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
val isCrashDetectionAvailable: Boolean
```

{% endtab %}
{% endtabs %}

This property returns `true` if:

* the required smartphone sensors are available and up and running;
* your API key is allowed to use the feature;

{% hint style="info" %}
If this property returns `false`, DriveKit will not start crash detection feature even if it has been previously activated with `activateCrashDetection()`.
{% endhint %}

## 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 use this function, you need to enable the interface with the following method and a [DKCrashFeedbackConfig](https://docs.drivequant.com/trip-analysis/android/references#dkcrashfeedbackconfig) object:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun enableCrashFeedback(config: DKCrashFeedbackConfig)
```

{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun disableCrashFeedback()
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
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 [here](/trip-analysis/android/runtime-permissions#full-screen-intent-permission).
{% endhint %}

## Listening to Crash events

`TripListener` interface provides two callbacks for crash events:

* `crashDetected(crashInfo:`[`DKCrashInfo`](https://docs.drivequant.com/trip-analysis/android/references#dkcrashinfo)`)`, triggered when a crash event is detected
* `crashFeedbackSent(crashInfo:`[`DKCrashInfo`](https://docs.drivequant.com/trip-analysis/android/references#dkcrashinfo)`, feedbackType:` [`CrashFeedbackType`](https://docs.drivequant.com/trip-analysis/android/references#crashfeedbacktype)`, severity:`[`CrashFeedbackSeverity`](https://docs.drivequant.com/trip-analysis/android/references#crashfeedbackseverity)`)`, triggered when crash feedback is enabled and a confirmed crash is detected. This callback will contain crash information and the feedback from the user.

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.


# 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.&#x20;

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

The DriveKit SDK is fully compatible with the [Apple iBeacon™](https://developer.apple.com/ibeacon/) standard.&#x20;

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setBeacons(beacons: List<BeaconData>)
```

{% endtab %}
{% endtabs %}

A detailed description of `BeaconData` class is available [here](/trip-analysis/ios/references#beacon).

{% hint style="info" %}
If you want to ignore `major` and `minor` values for trip detection, set them to -1.
{% endhint %}

{% hint style="info" %}
If you want to remove beacons from SDK configuration, just call the method with an empty array.
{% endhint %}

## 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setBeaconRequired(required: Boolean)
```

{% endtab %}
{% endtabs %}

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

{% hint style="info" %}
If you have configured the beacon and the [bluetooth device](/trip-analysis/android/bluetooth-usage#bluetooth-device-required) as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.
{% endhint %}

## 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.<br>

{% hint style="danger" %}
If this advanced configuration is not used correctly, it may result in poor trip detection performance.&#x20;

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

### 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
var allowBeaconTripStart: Boolean
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
This feature has no effect if the automatic trip detection mode is disabled.
{% endhint %}


# 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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getBluetoothPairedDevices(): List<BluetoothData>
```

{% endtab %}
{% endtabs %}

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

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setBluetoothDevices(devices: List<BluetoothData>)
```

{% endtab %}
{% endtabs %}

A detailed description of BluetoothData class is available [here](/trip-analysis/android/references#bluetoothdata).

{% hint style="info" %}
If you want to remove Bluetooth devices from SDK configuration, just call the method with an empty list.
{% endhint %}

## 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`:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setBluetoothDeviceRequired(required: Boolean)
```

{% endtab %}
{% endtabs %}

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`:

{% hint style="info" %}
If you have configured the [beacon](/trip-analysis/android/beacon-usage#beacon-required) and the bluetooth device as required, trips will be recorded if at least a beacon or a bluetooth device is detected during the trip.
{% endhint %}


# 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.

{% hint style="warning" %}
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 [`sdkStateChanged(state: State)`](/trip-analysis/android/triplistener)callback, by checking if `state` is `INACTIVE`.
{% endhint %}

## Set metadata

You can add additional metadata to your trip by calling the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun setTripMetaData(metaData: HashMap<String, String>?)
```

{% endtab %}
{% endtabs %}

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:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun getTripMetaData(): HashMap<String, String>?
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Note: Any modification on the returned object has no effect on the metadata sent with a trip.
{% endhint %}

## Update metadata

To update a value in metadata, call the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun updateTripMetaData(key: String, value: String?)
```

{% endtab %}
{% endtabs %}

## Delete a specific metadata

To delete a specific value in metadata, call the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun deleteTripMetadata(key: String)
```

{% endtab %}
{% endtabs %}

## Delete all metadata

To delete all values in metadata, call this method:

{% tabs %}
{% tab title="DriveKitTripAnalysis" %}

```kotlin
fun deleteTripMetadata()
```

{% endtab %}
{% endtabs %}


# 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:

```kotlin
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

If [`TripResult`](#tripresult) is `TripValid`, it means that the analyzed trip is valid. Additional information are available:

<table><thead><tr><th width="241">Field</th><th width="269">Type</th><th>Description</th></tr></thead><tbody><tr><td>itinId</td><td><code>String</code></td><td>Unique trip identifier generated after the trip data analysis.</td></tr><tr><td>localTripId</td><td><code>String</code></td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object.</p></td></tr><tr><td>hasSafetyAndEcoDrivingScore</td><td><code>Boolean</code></td><td>If <code>false</code>, it means that the trip is too short to be analyzed.<br>In this case, there is no safety or ecodriving score.</td></tr><tr><td>info</td><td><code>List&#x3C;</code><a href="#tripresponseinfo"><code>TripResponseInfo</code></a><code>></code></td><td>The DriveQuant servers returns a list of information codes. These are not errors.</td></tr></tbody></table>

This object also provides a method, `getTrip()`, to retrieve from the local database the saved [Trip](#trip).

#### 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

If [`TripResult`](#tripresult) is `TripError`, it means that the trip has been analyzed but an error occurred and data is not valid. Additional error information are available:

| Property          | Type                | Description                                                                                                                                                                                                                                                                         |
| ----------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| localTripId       | `String`            | <p>Local and unique trip identifier generated by DriveKit SDK.</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="#trip">Trip</a> object. <code>itinId</code> corresponds to the unique trip identifier generated after the data analysis.</p> |
| 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

<table><thead><tr><th width="261.66666666666663">Field</th><th width="169">Type</th><th>Description</th></tr></thead><tbody><tr><td>itinId</td><td><code>String</code></td><td>Trip unique identifier.</td></tr><tr><td>endDate</td><td><code>Date</code></td><td>The end date of the trip.</td></tr><tr><td>startDate</td><td><code>Date?</code></td><td>The start date of the trip.</td></tr><tr><td>vehicleId</td><td><code>String?</code></td><td>The identifier of the vehicle used for this trip, if known.</td></tr><tr><td>transportationMode</td><td><code>TransportationMode</code></td><td>The transportation mode used for this trip, among: <code>CAR</code>, <code>MOTO</code>, <code>TRUCK</code>, <code>BUS</code>, <code>TRAIN</code>, <code>BOAT</code>, <code>BIKE</code>, <code>FLIGHT</code>, <code>SKIING</code>, <code>ON_FOOT</code>, <code>IDLE</code>, <code>OTHER</code>, <code>UNKNOWN</code>.</td></tr><tr><td>declaredTransportationMode</td><td><code>DeclaredTransportationMode?</code></td><td>The transportation mode declared by the user. See <a href="#declaredtransportationmode">DeclaredTransportationMode</a>.</td></tr><tr><td>departureAddress</td><td><code>String</code></td><td>The full address of the departure of the trip.</td></tr><tr><td>departureCity</td><td><code>String</code></td><td>The city of the departure of the trip.</td></tr><tr><td>departurePostalCode</td><td><code>String</code></td><td>The postal code of the trip departure.</td></tr><tr><td>departureState</td><td><code>String</code></td><td>The state of the trip departure.</td></tr><tr><td>departureCountry</td><td><code>String</code></td><td>The country of the trip departure</td></tr><tr><td>arrivalAddress</td><td><code>String</code></td><td>The full address of the arrival of the trip.</td></tr><tr><td>arrivalCity</td><td><code>String</code></td><td>The city of the arrival of the trip.</td></tr><tr><td>arrivalPostalCode</td><td><code>String</code></td><td>The postal code of the trip arrival.</td></tr><tr><td>arrivalState</td><td><code>String</code></td><td>The state of the trip arrival.</td></tr><tr><td>arrivalCountry</td><td><code>String</code></td><td>The country of the trip arrival.</td></tr><tr><td>unscored</td><td><code>Boolean</code></td><td><code>true</code> if has no safety and eco-driving score.</td></tr><tr><td>occupantInfo</td><td><code>OccupantInfo?</code></td><td><p>Indicating whether the occupant was the driver or a passenger. </p><p>See <a href="#occupantinfo">OccupantInfo</a>.</p></td></tr><tr><td>metaData</td><td><code>Map&#x3C;String, String></code></td><td>Your specific data attached to the trip.  See <a href="/pages/RJhJdxQxqKzkamaSK2qZ">Custom metadata</a>.</td></tr><tr><td>tripStatistics</td><td><code>TripStatistics?</code></td><td>Indicators that characterize the trip conditions. See <a href="/pages/-LmyNRA_muNPJIeFBcbX#itinerarystatistics">ItineraryStatistics</a>.</td></tr><tr><td>brakeWear</td><td><code>BrakeWear?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">BrakeWear</a>.</td></tr><tr><td>tireWear</td><td><code>TireWear?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">TireWear</a>.</td></tr><tr><td>ecoDriving</td><td><code>EcoDriving?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#eco-driving">EcoDriving</a>.</td></tr><tr><td>ecoDrivingContexts</td><td><code>List&#x3C;EcoDrivingContext></code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-eco-driving">AdvancedEcoDriving</a>.</td></tr><tr><td>fuelEstimation</td><td><code>FuelEstimation?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#fuel-estimation">FuelEstimation</a>.</td></tr><tr><td>fuelEstimationDrivingContexts</td><td><code>List&#x3C;FuelEstimationDrivingContext></code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-fuel-estimation">Advanced fuel estimation</a>.</td></tr><tr><td>safety</td><td><code>Safety?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#safety">Safety</a>.</td></tr><tr><td>safetyContexts</td><td><code>List&#x3C;SafetyContext></code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-safety">AdvancedSafety</a>.</td></tr><tr><td>safetyEvents</td><td><code>List&#x3C;SafetyEvent>?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#safetyevents">SafetyEvents</a>.</td></tr><tr><td>driverDistraction</td><td><code>DriverDistraction?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#driver-distraction-score">DriverDistraction</a>.</td></tr><tr><td>pollutants</td><td><code>Pollutants?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#pollutants">Pollutants</a>.</td></tr><tr><td>speedingStatistics</td><td><code>SpeedingStatistics?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#speed-limit">Speed Limit</a>.</td></tr><tr><td>speedLimitContexts</td><td><code>List&#x3C;SpeedLimitContext>?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#speedlimitcontexts">SpeedLimitContexts</a>.</td></tr><tr><td>calls</td><td><code>List&#x3C;Call>?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#call">CallEvent</a>.</td></tr><tr><td>energyEstimation</td><td><code>EnergyEstimation?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#energyestimation">EnergyEstimation</a>.</td></tr><tr><td>advancedEnergyEstimations</td><td><code>List&#x3C;AdvancedEnergyEstimation>?</code></td><td>See <a href="/pages/-LmyNRA_muNPJIeFBcbX#advancedenergyestimation">AdvancedEnergyEstimation</a>.</td></tr></tbody></table>

### OccupantInfo

<table><thead><tr><th width="188">Field</th><th width="159">Type</th><th>Description</th></tr></thead><tbody><tr><td>role</td><td><code>OccupantRole</code></td><td><p>Indicates the role of the occupant.</p><p>See <a href="#occupantrole">OccupantRole</a>.</p></td></tr><tr><td>passengerProbability</td><td>Int</td><td>Probability, expressed as a percentage, that the vehicle occupant is a passenger.</td></tr></tbody></table>

### OccupantRole

<table><thead><tr><th width="206">Value</th><th>Description</th></tr></thead><tbody><tr><td>DRIVER</td><td>The vehicle occupant is very likely to be a driver.</td></tr><tr><td>PASSENGER</td><td>The vehicle occupant is very likely to be a passenger.</td></tr><tr><td>UNAVAILABLE</td><td>The trip data and historical information about the user's habits do not allow determining whether the occupant is a driver or a passenger. In this case, we recommend considering the occupant as the driver for this trip.</td></tr><tr><td>NOT_APPLICABLE</td><td>The trip was made using public transportation (such as train or bus) or by a mode of transport other than a car (e.g., bicycle, boat, plane). In these cases, driver/passenger detection is not performed.</td></tr></tbody></table>

### 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:

<table><thead><tr><th width="197">Field</th><th width="214">Type</th><th>Description</th></tr></thead><tbody><tr><td>transportationMode</td><td><code>TransportationMode</code></td><td>The transportation mode declared by the user for this trip, among: <code>CAR</code>, <code>MOTO</code>, <code>TRUCK</code>, <code>BUS</code>, <code>TRAIN</code>, <code>BOAT</code>, <code>BIKE</code>, <code>FLIGHT</code>, <code>SKIING</code>, <code>ON_FOOT</code>, <code>IDLE</code>, <code>OTHER</code>, <code>UNKNOWN</code>.</td></tr><tr><td>passenger</td><td><code>Boolean?</code></td><td><code>true</code> if the trip was made as a passenger, <code>false</code> if the trip was made as the driver.</td></tr><tr><td>comment</td><td><code>String?</code></td><td>The comment associated to this declaration.</td></tr></tbody></table>

## DKTripRecordingStartedState

This object is returned in the [`TripListener`](/trip-analysis/android/triplistener)'s `tripRecordingStarted()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresult">TripResult</a> after DriveQuant platform's analysis.</td></tr></tbody></table>

## DKTripRecordingConfirmedState

This object is returned in the [`TripListener`](/trip-analysis/android/triplistener)'s `tripRecordingConfirmed()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresult">TripResult</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date</td><td>Date when the trip entered into the confirmation state.</td></tr></tbody></table>

## DKTripRecordingCanceledState

This object is returned in the [`TripListener`](/trip-analysis/android/triplistener)'s `tripRecordingCanceled()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the recalculated trip start date returned in <a href="#tripresult">TripResult</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date?</td><td>Date when the trip was confirmed if the trip entered into the confirmation state.</td></tr><tr><td>cancelationReason</td><td>DKTripCancelationReason</td><td><p>Indicates how the trip was canceled.</p><p>Possible values are described <a href="#dktripcancelationreason">here</a>.</p></td></tr></tbody></table>

## DKTripRecordingFinishedState

This object is returned in the [`TripListener`](/trip-analysis/android/triplistener)'s `tripRecordingFinished()` callback.

<table><thead><tr><th width="205">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>localTripId</td><td>String</td><td><p>Local and unique trip identifier generated by DriveKit SDK</p><p>⚠️ It is different from the <code>itinId</code> property returned in the <a href="/pages/-LnMH5ErH5WNrLs46vVd#trip">Trip</a> object, which corresponds to the unique trip identifier generated after the data analysis.</p></td></tr><tr><td>startMode</td><td>StartMode</td><td>Indicates how the trip started. Possible values are describe <a href="#startmode">here</a>.</td></tr><tr><td>recordingStartDate</td><td>Date</td><td>Date when DriveKit has started the trip recording.<br>⚠️  It is not the trip start date returned in <a href="#tripresult">TripResult</a> after DriveQuant platform's analysis.</td></tr><tr><td>recordingConfirmationDate</td><td>Date</td><td>Date when the trip entered into the confirmation state.</td></tr><tr><td>recordingEndDate</td><td>Date</td><td>Date when DriveKit has terminated the trip recording.<br>⚠️  It is not the trip end date returned in <a href="#tripresult">TripResult</a> after DriveQuant platform's analysis.</td></tr></tbody></table>

## 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             | Trip started manually by calling the method [startTrip()](/trip-analysis/android/trip-management#manually-start-a-trip) |
| 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                         | Trip canceled by calling the method [`cancelTrip`](/trip-analysis/android/trip-management#cancel-a-trip)                                                                                                                                                           |
| 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                   | Trip canceled because the beacon was not detected while it was [required](/trip-analysis/android/beacon-usage#beacon-required)                                                                                                                                     |
| NO\_BLUETOOTH\_DEVICE        | Trip canceled because the Bluetooth device was not detected while it was [required](/trip-analysis/android/bluetooth-usage#bluetooth-device-required).                                                                                                             |
| MISSING\_CONFIGURATION       | Trip canceled because DriveKit was not configured                                                                                                                                                                                                                  |
| NO\_LOCATION\_DATA           | Trip canceled because no location data was recorded                                                                                                                                                                                                                |
| RESET                        | Trip canceled because SDK configuration has been [reset](/get-started-drivekit/android/advanced-configurations#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                  | <p>The trip recording has been canceled due to an app termination.<br>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.</p> |

## 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.

```kotlin
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     | [Vehicle body type](/trip-analysis/rest-services/references#vehicle-body-type)                                                                                                                           | 1                               |
| carEngineIndex       | Int     | [Engine type](/trip-analysis/rest-services/references#engine-type)                                                                                                                                       | 1                               |
| carPower             | Double  | 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.7355$$ (min: 40 hp, max 450 hp) | 150                             |
| carMass              | Double  | Vehicle mass in kg (min: 700 kg, max: 3500 kg)                                                                                                                                                           | 1400                            |
| carGearboxIndex      | Int     | [Gearbox type](/trip-analysis/rest-services/references#gearbox-type)                                                                                                                                     | 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?    | [Drive wheels type](/trip-analysis/rest-services/references#drive-wheels-type)                                                                                                                           | 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.

<table><thead><tr><th>Attribute</th><th width="264.3333333333333">Type</th><th>Description</th></tr></thead><tbody><tr><td>macAddress</td><td>String</td><td>Required MAC address of the device</td></tr><tr><td>name</td><td>String</td><td>Optional display name of the device</td></tr></tbody></table>

## DKCrashInfo

Crash information object have the following structure:

| Attribute       | Type            | Description                                                                                                                                                                                                               |
| --------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| crashId         | String          | Crash unique identifier                                                                                                                                                                                                   |
| date            | Date            | <p>Crash date</p><p>Example: <code>2023-03-07T09:13:22.461+0200</code></p>                                                                                                                                                |
| 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?         | <p>When a crash is confirmed and <a href="/pages/leo4dxpUiyoESHjb6FH0">push crash data</a> is activated, an URL of the map that will display the location data is returned.</p><p>Otherwise, it is <code>null</code>.</p> |

## DKCrashFeedbackConfig

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

| Attribute              | Type                          | Description                                                                                                                                                                                                                                        |
| ---------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| notification           | `DKCrashFeedbackNotification` | Configuration of the notification                                                                                                                                                                                                                  |
| crashVelocityThreshold | Double                        | <p>Minimal speed when the crash occurred.</p><p>For example, if <code>crashVelocityThreshold</code> is set at 20 km/h and a crash occurred at 10 km/h, feedback will not be sent to the user. </p><p><strong>Default value</strong> : 0.0 km/h</p> |

## DKCrashFeedbackNotification

<table><thead><tr><th>Attribute</th><th width="270.3333333333333">Type</th><th>Description</th></tr></thead><tbody><tr><td>icon</td><td>Int</td><td>Resource identifier of the  notification icon</td></tr><tr><td>channelId</td><td>String</td><td>Android channel identifier.<br><strong>Default value:</strong> <code>dq_sdk_crash_channel</code></td></tr><tr><td>notificationId</td><td>Int</td><td>Android notification identifier</td></tr><tr><td>title</td><td>String</td><td>Title that appears on the notification</td></tr><tr><td>message</td><td>String</td><td>Message that appears on the notification</td></tr><tr><td>activity</td><td>Class&#x3C;*></td><td>Activity to display</td></tr><tr><td>crashAlert</td><td><code>DKCrashAlert</code></td><td>Object that describes how the user will be noticed when a feedback is asked <strong>Default value</strong> : <code>SILENCE</code></td></tr></tbody></table>

## 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  |

### DKTripLocation

<table data-full-width="false"><thead><tr><th>Property/Method</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td>Date</td><td>Date of the end of trip.</td></tr><tr><td>latitude</td><td>Double</td><td>Latitude of the end of the trip.</td></tr><tr><td>longitude</td><td>Double</td><td>Longitude of the end of the trip.</td></tr><tr><td>accuracyMeter</td><td>Double</td><td>GPS data accuracy value in meters.</td></tr><tr><td>fun getAccuracyLevel()</td><td>DKCoordinateAccuracy</td><td>GPS data accuracy level. Possible values are described below.</td></tr></tbody></table>

### 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. |

## TripResponseStatus (Deprecated)

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

### TripValid

If [`TripResponseStatus`](#tripresponsestatus-deprecated) is `TripValid`, it means that the analyzed trip is valid. Additional information are available:

| Field                       | Type                                        | Description                                                                                                                                |
| --------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| hasSafetyAndEcoDrivingScore | Boolean                                     | <p>If <code>false</code>, it means that the trip is too short to be analyzed.<br>In this case, there is no safety or ecodriving score.</p> |
| info                        | List<[TripResponseInfo](#tripresponseinfo)> | The DriveQuant servers returns a list of information codes. These are not errors.                                                          |

### TripResponseError

If [`TripResponseStatus`](#tripresponsestatus-deprecated) 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 [`tripResponseError`](#tripresponseerror-enum) enum.

## CancelTrip (Deprecated)

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

| Value                        | Description                                                                                                                     |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| USER                         | Trip cancelled by calling the method [`cancelTrip`](/trip-analysis/android/trip-management#cancel-a-trip)                       |
| 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                   | Trip cancelled because the beacon was not detected while it was [required](/trip-analysis/android/beacon-usage#beacon-required) |
| MISSING\_CONFIGURATION       | Trip cancelled because DriveKit was not configured                                                                              |
| NO\_GPS\_DATA                | Trip cancelled because no GPS data was recorded                                                                                 |
| RESET                        | Trip cancelled because SDK configuration has been [reset](/get-started-drivekit/android/advanced-configurations#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) <a href="#deviceconfigevent" id="deviceconfigevent"></a>

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

### BluetoothSensorStateChanged <a href="#bluetooth_sensor_state_changed" id="bluetooth_sensor_state_changed"></a>

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 <a href="#bluetooth_sensor_state_changed" id="bluetooth_sensor_state_changed"></a>

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.&#x20;

It contains 3 main features :&#x20;

1. Working hours ;&#x20;
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.&#x20;

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:&#x20;

* professional,&#x20;
* personal,&#x20;
* or not recorded at all.

<figure><img src="/files/p7OuRHBOQPXPBdgwaz3M" alt=""><figcaption><p>Working hours screen</p></figcaption></figure>

### 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.&#x20;

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.

![Feedback crash graphical interface](/files/euIqzcaJa9djzTOBWkEU)

### 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.

<figure><img src="/files/CnqKvdXgz5qI81V2bJ3T" alt=""><figcaption><p>The trip recording widget when no trip is in progress (left) and when a trip is analysed (right)</p></figcaption></figure>

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.

<figure><img src="/files/hTvzoNN3LGlJjPOkvHyb" alt=""><figcaption><p>Options proposed to the user when a trip is being recorded</p></figcaption></figure>


# iOS


# Get started

## **Prerequisite**

Before starting DriveKit Trip Analysis UI integration, make sure that you have initialized TripAnalysis and [CommonUI](/common-ui/ios/get-started#initialization) modules, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-core-module).

## **Integration**

The Trip Analysis UI module is available on Swift Package Manager and Cocoapods master repo.

{% hint style="info" %}
On this [Github repository](https://github.com/DriveQuantPublic/drivekit-ui-ios), you also have a demo app and source code of Driver Data UI that you can use as an example.
{% endhint %}

### Swift Package Manager

#### Via Xcode:

* In Xcode, add the DriveKitUI SDK by navigating to File > Add Package Dependencies...
* In the prompt that appears, enter the DriveKitUI repository:\
  `https://github.com/DriveQuantPublic/drivekit-ui-ios.git`&#x20;
* Include DriveKitTripAnalysisUI in your app.

#### Via Package.swift:

* To integrate DriveKitUI to a Swift package via a `Package.swift` file, you can add DriveKitUI to the dependencies array of your package. For more details, see the [Swift Package Manager documentation](https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html#package-dependency).

```swift
dependencies: [
  .package(name: "DriveKitUI",
           url: "https://github.com/DriveQuantPublic/drivekit-ui-ios.git",
           from: "2.0.0"),
  // ...
],
```

* Then in your target, add DriveKitTripAnalysisUI to the dependencies array of that target:

```swift
.target(
  name: "MyTarget",
  dependencies: [
    .product(name: "DriveKitTripAnalysisUI", package: "DriveKitUI"),
    // ...
  ]
),
```

### Cocoapods (deprecation scheduled for the end of 2025)

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

{% tabs %}
{% tab title="Podfile" %}

```ruby
target 'my-target' do
  pod 'DriveKitTripAnalysisUI'
end
```

{% endtab %}
{% endtabs %}

Then, run `pod install`.

## **Initialization**

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-core-module), the Trip Analysis UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitTripAnalysisUI:

```swift
import DriveKitTripAnalysisUI
```

Then, to initialize Trip Analysis UI SDK in your app, you must call the initialization method in `didFinishLaunchingWithOptions` method of your AppDelegate:

{% tabs %}
{% tab title="AppDelegate.swift" %}

```swift
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()
    ...    
}
```

{% endtab %}
{% endtabs %}


# 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".&#x20;

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

You can get that screen by calling the following method:

```swift
DriveKitNavigationController.shared.tripAnalysisUI?.getWorkingHoursViewController()
```


# 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:

```swift
DriveKitTripAnalysisUI.shared.enableCrashFeedback(roadsideAssistanceNumber: String, config: DKCrashFeedbackConfig)
```

With the following parameters:

<table><thead><tr><th width="272.39014373716634">Attribute</th><th width="249.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>roadsideAssistanceNumber</td><td>String</td><td>Emergency number that will be called if there is a crash.</td></tr><tr><td>config</td><td>DKCrashFeedbackConfig</td><td>Configuration of the feedback<strong>.</strong></td></tr></tbody></table>

**DKCrashFeedbackConfig**

<table><thead><tr><th width="234.73649449994411">Attribute</th><th width="150">Type</th><th>Description</th></tr></thead><tbody><tr><td>notification</td><td>DKCrashFeedbackNotification</td><td>Configuration of the notification.</td></tr><tr><td>crashVelocityThreshold</td><td>Double</td><td>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. <strong>Default value :</strong> 0.0 km/h</td></tr></tbody></table>

**DKCrashFeedbackNotification**

<table><thead><tr><th width="221.80154561602978">Attribute</th><th width="173.2219250021814">Type</th><th>Description</th></tr></thead><tbody><tr><td>title</td><td>String</td><td>Title that appears on the notification.</td></tr><tr><td>message</td><td>String</td><td>Message that appears on the notification</td></tr><tr><td>crashAlert</td><td>DKCrashAlert</td><td>Object that describes how the user will be noticed when a feedback is asked. <strong>Default value :</strong> SILENCE</td></tr></tbody></table>

**DKCrashAlert**

<table><thead><tr><th width="221.80154561602978">Attribute</th><th width="254.46761211233252">Description</th></tr></thead><tbody><tr><td>silence</td><td>Device will not vibrate or ring</td></tr><tr><td>vibration</td><td>Device will vibrate</td></tr><tr><td>soundAndVibration</td><td>Device will ring and vibrate</td></tr></tbody></table>

## Disable Feedback crash detection

To disable crash detection feedback, call the following method:

```swift
DriveKitTripAnalysisUI.shared.disableCrashFeedback()
```

## **Test your integration with the crash simulator**

In order to check your integration and test the crash detection feature, you can use the trip simulator described in section [simulate a crash during a trip.](/trip-analysis/trip-simulator/ios#simulate-a-crash-during-a-trip)

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.&#x20;

This information can be used t&#x6F;**:**&#x20;

* trigger the intervention of an assistance service,&#x20;
* and initiate the accident management process.

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 <contact@drivequant.com>


# 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:

```swift
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.&#x20;

{% hint style="info" %}
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.
{% endhint %}

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).

{% hint style="warning" %}
**Warning**: This dialog won’t appear if the `DKTripRecordingUserMode` doesn’t allow the user to end a trip.
{% endhint %}

## 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.<br>
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.<br>

The default value is `.startStop`.

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

```swift
DriveKitTripAnalysisUI.shared.tripRecordingUserMode = .startStop
```


# 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.

<figure><img src="/files/5fwS0FaU6pAaySt8hqQ9" alt=""><figcaption></figcaption></figure>

To integrate and display this feature within your application, invoke the following method:

```swift
DriveKitTripAnalysisUI.shared.getTripSharingViewController()
```


# Android


# Get started

## Prerequisite&#x20;

Before starting DriveKit Vehicle UI integration, make sure that TripAnalysis and [CommonUI](/common-ui/android/get-started#initialization) modules are initialized, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk).&#x20;

## Integration&#x20;

To add the Trip Analysis UI module to your app, add the following lines to your dependencies in your application build.gradle file:

{% tabs %}
{% tab title="build.gradle" %}

```gradle
dependencies {
   implementation 'com.drivequant.drivekit:drivekit-trip-analysis-ui:$drivekitui_version'
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Replace `$drivekitui_version` with the DriveKit version you are using in your app
{% endhint %}

On a[ Github repository](https://github.com/DriveQuantPublic/drivekit-ui-android), you can find a demo app and the source code of Permissions Utils UI that you can use as an example.

## **Initialization**

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), the Trip Analysis UI module must also be manually initialized.&#x20;

Then, to initialize the Trip Analysis UI module in your app, you must call the initialization method in `onCreate` method of your Application class:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class MyApplication : Application() {
   override fun onCreate() {
      super.onCreate()
      DriveKit.initialize()
      DriveKitTripAnalysis.initialize(...)
      DriveKitUI.initialize()
      DriveKitTripAnalysisUI.initialize()
      (…)
   }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class DriveQuantApplication extends Application {
   @Override
   public void onCreate() {
   	super.onCreate();
   	DriveKit.initialize();
        DriveKitTripAnalysis.initialize(...)
   	DriveKitUI.initialize();
   	DriveKitTripAnalysisUI.initialize();
   	(…)
   }
}
```

{% endtab %}
{% endtabs %}


# 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`.&#x20;

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

You can start displaying that screen by calling the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitNavigationController.tripAnalysisUIEntryPoint?.startWorkingHoursActivity(context)
```

{% endtab %}

{% tab title="Java" %}

```java
TripAnalysisUIEntryPoint entryPoint = DriveKitNavigationController.INSTANCE.getTripAnalysisUIEntryPoint();
if (entryPoint != null) {
   entryPoint.startWorkingHoursActivity(this);
}
```

{% endtab %}
{% endtabs %}


# 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:

{% tabs %}
{% tab title="DriveKitTripAnalysisUI" %}

```kotlin
fun enableCrashFeedback(roadsideAssistanceNumber: String, config: DKCrashFeedbackConfig)
```

{% endtab %}
{% endtabs %}

With the following parameters:

<table><thead><tr><th width="272.39014373716634">Attribute</th><th width="249.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>roadsideAssistanceNumber</td><td>String</td><td>Emergency number that will be called if there is a crash.</td></tr><tr><td>config</td><td>DKCrashFeedbackConfig</td><td>Configuration of the feedback<strong>.</strong></td></tr></tbody></table>

**DKCrashFeedbackConfig**

<table><thead><tr><th width="234.73649449994411">Attribute</th><th width="150">Type</th><th>Description</th></tr></thead><tbody><tr><td>notification</td><td>DKCrashFeedbackNotification</td><td>Configuration of the notification.</td></tr><tr><td>crashVelocityThreshold</td><td>Double</td><td>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. <strong>Default value :</strong> 0.0 km/h</td></tr></tbody></table>

**DKCrashFeedbackNotification**

<table><thead><tr><th width="221.80154561602978">Attribute</th><th width="173.2219250021814">Type</th><th>Description</th></tr></thead><tbody><tr><td>title</td><td>String</td><td>Title that appears on the notification.</td></tr><tr><td>message</td><td>String</td><td>Message that appears on the notification</td></tr><tr><td>crashAlert</td><td>DKCrashAlert</td><td>Object that describes how the user will be noticed when a feedback is asked. <strong>Default value :</strong> SILENCE</td></tr></tbody></table>

**DKCrashAlert**

<table><thead><tr><th width="221.80154561602978">Attribute</th><th width="254.46761211233252">Description</th></tr></thead><tbody><tr><td>SILENCE</td><td>Device will not vibrate or ring</td></tr><tr><td>VIBRATION</td><td>Device will vibrate</td></tr><tr><td>SOUND_AND_VIBRATION</td><td>Device will ring and vibrate</td></tr></tbody></table>

## Disable Feedback crash detection

To disable crash detection feedback, call the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysisUI" %}

```kotlin
fun disableCrashFeedback()
```

{% endtab %}
{% endtabs %}

## **Test your integration with the crash simulator**

In order to check your integration and test the crash detection feature, you can use the trip simulator described in section [simulate a crash during a trip](/trip-analysis/trip-simulator/android#simulate-a-crash-during-a-trip).

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.&#x20;

This information can be used t&#x6F;**:**&#x20;

* trigger the intervention of an assistance service,&#x20;
* and initiate the accident management process.

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 <contact@drivequant.com>&#x20;


# 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:

```xml
<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" />
```

The second way is getting it from `DriveKitTripAnalysisUI`:

{% tabs %}
{% tab title="DriveKitTripAnalysisUI" %}

```kotlin
fun newTripRecordingButtonFragment(): DKTripRecordingButton
```

{% endtab %}
{% endtabs %}

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.&#x20;

{% hint style="warning" %}
**Warning**: This dialog won’t appear if the `DKTripRecordingUserMode` doesn’t allow the user to end a trip.
{% endhint %}

## 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.<br>
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.<br>
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.<br>
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&#x20;

The default value is `START_STOP`.

To set the button mode, call the following method:

{% tabs %}
{% tab title="DriveKitTripAnalysisUI" %}

```kotlin
var tripRecordingUserMode: DKTripRecordingUserMode
```

{% endtab %}
{% endtabs %}


# 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.

<figure><img src="/files/KKsN43PWxWszK08smlUA" alt=""><figcaption></figcaption></figure>

To integrate and display this feature within your application, invoke the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitTripAnalysisUI.startTripSharingActivity(context)
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitTripAnalysisUI.INSTANCE.startTripSharingActivity(context);
```

{% endtab %}
{% endtabs %}


# REST services


# 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.&#x20;

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).

{% hint style="info" %}
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.
{% endhint %}

This section explains how to query the trip analysis API, how driving indicators are computed and how they are structured.

DriveQuant services provide additional data by collecting all vehicle trips so you can easily retrieve statistics for each of your vehicles. We recommend to [add a new vehicle](/backend/vehicle/create-a-vehicle) before requesting the trip analysis API if you target a vehicule mantenance use case.

## Trip

<mark style="color:green;">`POST`</mark> `https://service.drivequant.com/v2/trip`

This method returns all driving analytics calculated by DriveQuant for a trip.&#x20;

#### 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                    |

{% tabs %}
{% tab title="200 This is an example of trip API response. A detailed description of value is available below." %}

```javascript
  {
    "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 CITY>",
        "arrivalCity": "<ARRIVAL CITY>",
        "departureAddress": "<DEPARTURE ADDRESS>",
        "arrivalAddress": "<ARRIVAL ADDRESS>",
        "departureState": "<DEPARTURE STATE>",
        "arrivalState": "<ARRIVAL STATE>",
        "departurePostalCode": "<DEPARTURE POSTAL CODE>",
        "arrivalPostalCode": "<ARRIVAL POSTAL CODE>",
        "departureCountry": "<DEPARTURE COUNTRY>",
        "arrivalCountry": "<ARRIVAL COUNTRY>"
    },
    "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
    }
  ]
  }
```

{% endtab %}

{% tab title="201 " %}

```
```

{% endtab %}
{% endtabs %}

## 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).&#x20;

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.
3. **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 [contact DriveQuant](mailto:contact@drivequant.com) sales department to find out the best pricing model.

{% hint style="warning" %}
The Account object must contain the **account** and the **userId** or **vehicleId** attributes.
{% endhint %}

### Route

<table><thead><tr><th width="187.66666666666666">Field</th><th width="178">Type</th><th>Description</th></tr></thead><tbody><tr><td>gpsVelocity</td><td><code>array[double]</code></td><td>GPS speed vector in km/h</td></tr><tr><td>latitude</td><td><code>array[double]</code></td><td>Latitude vector in degree</td></tr><tr><td>longitude</td><td><code>array[double]</code></td><td>Longitude vector in degree</td></tr><tr><td>gpsAccuracy</td><td><code>array[double]</code></td><td>GPS accuracy vector in meter</td></tr><tr><td>gpsElevation</td><td><code>array[double]</code></td><td>Elevation vector in meter</td></tr><tr><td>gpsHeading</td><td><code>array[double]</code></td><td>Heading vector in degree</td></tr><tr><td>gpsDate</td><td><code>array[double]</code></td><td>GPS timestamp vector in second</td></tr><tr><td>vehVelocity</td><td><code>array[double]</code></td><td>Vehicle speed vector in km/h</td></tr><tr><td>vehEngineSpeed</td><td><code>array[double]</code></td><td>Engine speed vector in rotation per minute</td></tr><tr><td>vehTankLevel</td><td><code>array[double]</code></td><td>Fuel tank volume in liter</td></tr><tr><td>vehWheelAngle</td><td><code>array[double]</code></td><td>Steering angle vector in degree</td></tr><tr><td>batteryVoltage</td><td><code>array[double]</code></td><td>Measurement of the car battery voltage vector in volt</td></tr><tr><td>vehDate</td><td><code>array[double]</code></td><td>Vehicle date timestamp vector in second</td></tr></tbody></table>

{% hint style="warning" %}

* 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**.
* **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 [contact us](mailto:%20contact@drivequant.com) to determine what alternative can be applied.
  {% endhint %}

### Vehicle

<table><thead><tr><th width="235.66666666666666">Field</th><th width="100">Type</th><th>Description</th></tr></thead><tbody><tr><td>carTypeIndex</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#vehicle-body-type">Vehicle body type</a></td></tr><tr><td>carEngineIndex</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#engine-type">Engine type</a></td></tr><tr><td>carPower</td><td><code>double</code></td><td>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: <span class="math">P [hp] = P [kW] / 0.7355</span></td></tr><tr><td>carMass</td><td><code>double</code></td><td>Vehicle mass in kg</td></tr><tr><td>carGearboxIndex</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#gearbox-type">Gearbox type</a></td></tr><tr><td>carConsumption</td><td><code>double</code></td><td>Combined fuel consumption [l/100km] measured during the New European Driving Cycle (NEDC)</td></tr><tr><td>carAutoGearboxNumber</td><td><code>int</code></td><td>Number of gear ratios for the automatic gearbox. This parameter is taken into account only if <code>carGearboxIndex</code> is set to 1</td></tr></tbody></table>

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.

<table><thead><tr><th width="195">Field</th><th width="137.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>startDate</td><td><code>date</code></td><td>Trip start date<br><em>Date format: <code>YYYY-MM-dd’T’HH:mm:ss.SSSZ</code></em></td></tr><tr><td>endDate</td><td><code>date</code></td><td>Trip end date<br><em>Date format: <code>YYYY-MM-dd’T’HH:mm:ss.SSSZ</code></em></td></tr><tr><td>departureCity</td><td><code>string</code></td><td>Name of the departure city</td></tr><tr><td>arrivalCity</td><td><code>string</code></td><td>Name of the arrival city</td></tr><tr><td>departureAddress</td><td><code>string</code></td><td>Departure full address</td></tr><tr><td>arrivalAddress</td><td><code>string</code></td><td>Arrival full address</td></tr><tr><td>departureState</td><td><code>string</code></td><td>Name of the departure state</td></tr><tr><td>arrivalState</td><td><code>string</code></td><td>Name of the arrival state</td></tr><tr><td>departurePostalCode</td><td><code>string</code></td><td>Postal code of the departure</td></tr><tr><td>arrivalPostalCode</td><td><code>string</code></td><td>Postal code of the arrival</td></tr><tr><td>departureCountry</td><td><code>string</code></td><td>Name of the departure country</td></tr><tr><td>arrivalCountry</td><td><code>string</code></td><td>Name of the arrival country</td></tr></tbody></table>

### 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

```javascript
{
	"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 CITY>",
	        "arrivalCity": "<ARRIVAL CITY>",
	        "departureAddress": "<DEPARTURE ADDRESS>",
	        "arrivalAddress": "<ARRIVAL ADDRESS>",
	        "departureState": "<DEPARTURE STATE>",
	        "arrivalState": "<ARRIVAL STATE>",
	        "departurePostalCode": "<DEPARTURE POSTAL CODE>",
	        "arrivalPostalCode": "<ARRIVAL POSTAL CODE>",
	        "departureCountry": "<DEPARTURE COUNTRY>",
	        "arrivalCountry": "<ARRIVAL COUNTRY>"
	},
	"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.

<table><thead><tr><th width="261.66666666666663">Field</th><th width="169">Type</th><th>Description</th></tr></thead><tbody><tr><td>itinId</td><td><code>string</code></td><td>Trip unique identifier</td></tr><tr><td>status</td><td><code>boolean</code></td><td><code>true</code> if no problem, <code>false</code> otherwise</td></tr><tr><td>comments</td><td><code>array[object]</code></td><td>see <a href="/pages/-LmyNRA_muNPJIeFBcbX#comment">Comment</a></td></tr><tr><td>itineraryStatistics</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#itinerarystatistics">ItineraryStatistics</a></td></tr><tr><td>itineraryData</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#itinerarydata">ItineraryData</a></td></tr><tr><td>ecoDriving</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#eco-driving">EcoDriving</a></td></tr><tr><td>advancedEcoDriving</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-eco-driving">AdvancedEcoDriving</a></td></tr><tr><td>fuelEstimation</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#fuel-estimation">FuelEstimation</a></td></tr><tr><td>advancedFuelEstimation</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-fuel-estimation">AdvancedFuelEstimation</a></td></tr><tr><td>safety</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#safety">Safety</a></td></tr><tr><td>advancedSafety</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#advanced-safety">AdvancedSafety</a></td></tr><tr><td>safetyEvents</td><td><code>array[object]</code></td><td>see <a href="/pages/-LmyNRA_muNPJIeFBcbX#safetyevents">SafetyEvent</a></td></tr><tr><td>tireWear</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">TireWear</a></td></tr><tr><td>brakeWear</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#tire-and-brake-wear-estimates">BrakeWear</a></td></tr><tr><td>pollutants</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#pollutants">Pollutants</a></td></tr><tr><td>userId</td><td><code>string</code></td><td>unique id of the user</td></tr><tr><td>firstname</td><td><code>string</code></td><td>first name of the user</td></tr><tr><td>lastname</td><td><code>string</code></td><td>Last name of the user</td></tr><tr><td>endDate</td><td><code>string</code></td><td>End date  of the trip</td></tr><tr><td>driverDistraction</td><td><code>object</code></td><td><a href="/pages/-LmyNRA_muNPJIeFBcbX#driver-distraction-score">DriverDistraction</a></td></tr><tr><td>distractionEvents</td><td><code>array[object]</code></td><td>see <a href="/pages/-LmyNRA_muNPJIeFBcbX#driver-distraction-events">DistractionEvents</a></td></tr><tr><td>callEvents</td><td><code>array[object]</code></td><td>see <a href="/pages/-LmyNRA_muNPJIeFBcbX#call">CallEvent</a></td></tr><tr><td>speedingStatistics</td><td><code>object</code></td><td><a href="https://docs.drivequant.com/trip-analysis/rest-services/trip#speed-limit">Speed Limit</a></td></tr><tr><td>speedingEvents</td><td><code>array[object]</code></td><td>see <a href="https://docs.drivequant.com/trip-analysis/rest-services/trip#speedingevents">SpeedingEvents</a></td></tr><tr><td>energyEstimation</td><td><code>object</code></td><td><a href="#energyestimation">EnergyEstimation</a></td></tr><tr><td>advancedEnergyEstimation</td><td><code>array[object]</code></td><td>see <a href="#advancedenergyestimation">AdvancedEnergyEstimation</a></td></tr></tbody></table>

### Comment

| Field     | Type     | Description       |
| --------- | -------- | ----------------- |
| errorCode | `int`    | Error code        |
| comment   | `string` | Error description |

{% hint style="success" %}
Possible values are described [here](/trip-analysis/rest-services/references#error-codes).
{% endhint %}

### 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).

![](https://lh4.googleusercontent.com/OTBTQqMP7kWCcv8AuyBp5bOdMVXA0PYuHjMWgZnwoKbW6cMptE13H8ck1QkvjJY71um4Mm77d7S9K1jGe6Rfql6ln7cUQe2gpHZusCf1vUhuOpw8PK10xE27XSByAn1X5W5fHJzI)

<table><thead><tr><th width="207">Field</th><th width="113.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>distance</td><td><code>double</code></td><td>Distance travelled in meter</td></tr><tr><td>speedMean</td><td><code>double</code></td><td>Mean vehicle speed in km/h</td></tr><tr><td>tripDuration</td><td><code>double</code></td><td>Total trip duration in second</td></tr><tr><td>drivingDuration</td><td><code>double</code></td><td>Vehicle movement duration in second</td></tr><tr><td>idlingDuration</td><td><code>double</code></td><td><p>Total duration of idling phases (vehicle stopped)</p><p> in second</p></td></tr><tr><td>drivingPercentage</td><td><code>double</code></td><td>Percentage of vehicle movement</td></tr><tr><td>idlingPercentage</td><td><code>double</code></td><td>Percentage of idling phases</td></tr><tr><td>subdispNb</td><td><code>int</code></td><td>Number of sub-displacements detected during the trip</td></tr><tr><td>meteo</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#weather-code">Weather code</a></td></tr><tr><td>day</td><td><code>boolean</code></td><td><code>true</code> if day, <code>false</code> if night</td></tr><tr><td>weekDay</td><td><code>boolean</code></td><td><code>true</code>: Monday to Friday, <code>false</code>: Saturday to Sunday</td></tr><tr><td>transportationMode</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#transportation-mode">Transportation mode</a></td></tr></tbody></table>

### ItineraryData

<table><thead><tr><th width="195">Field</th><th width="137.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>startDate</td><td><code>date</code></td><td>Trip start date<br><em>Date format: <code>YYYY-MM-dd’T’HH:mm:ss.SSSZ</code></em></td></tr><tr><td>endDate</td><td><code>date</code></td><td>Trip end date<br><em>Date format: <code>YYYY-MM-dd’T’HH:mm:ss.SSSZ</code></em></td></tr><tr><td>departureCity</td><td><code>string</code></td><td>Name of the departure city</td></tr><tr><td>arrivalCity</td><td><code>string</code></td><td>Name of the arrival city</td></tr><tr><td>departureAddress</td><td><code>string</code></td><td>Departure full address</td></tr><tr><td>arrivalAddress</td><td><code>string</code></td><td>Arrival full address</td></tr><tr><td>departureState</td><td><code>string</code></td><td>Name of the departure state</td></tr><tr><td>arrivalState</td><td><code>string</code></td><td>Name of the arrival state</td></tr><tr><td>departurePostalCode</td><td><code>string</code></td><td>Postal code of the departure</td></tr><tr><td>arrivalPostalCode</td><td><code>string</code></td><td>Postal code of the arrival</td></tr><tr><td>departureCountry</td><td><code>string</code></td><td>Name of the departure country</td></tr><tr><td>arrivalCountry</td><td><code>string</code></td><td>Name of the arrival country</td></tr></tbody></table>

### 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.

<table><thead><tr><th width="162.66666666666666">Field</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td><code>double</code></td><td>Eco-driving score (min: 0, max: 10). If trip is too short to be scored, score is set to 11.</td></tr><tr><td>scoreAccel</td><td><code>double</code></td><td>Score of the acceleration phases. If trip is too short to be scored, score is set to 6.</td></tr><tr><td>scoreMain</td><td><code>double</code></td><td>Score of the stabilized speed phases. If trip is too short to be scored, score is set to 6.</td></tr><tr><td>scoreDecel</td><td><code>double</code></td><td>Score of the deceleration phases. If trip is too short to be scored, score is set to 6.</td></tr><tr><td>stdDevAccel</td><td><code>double</code></td><td>Standard deviation of acceleration score</td></tr><tr><td>stdDevMain</td><td><code>double</code></td><td>Standard deviation of stabilized speed score</td></tr><tr><td>stdDevDecel</td><td><code>double</code></td><td>Standard deviation of deceleration score</td></tr><tr><td>energyClass</td><td><code>int</code></td><td><p>See <a href="#energy-class">Energy Class</a>:</p><p>0: energy class A </p><p>1: energy class B</p><p>2: energy class C</p><p>3: energy class D</p><p>4: energy class E</p></td></tr></tbody></table>

#### 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 |

{% hint style="warning" %}
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
  {% endhint %}

#### 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 $$\mathrm{gCO\_2/km}$$.
* Class E corresponds to 1.5 x the NEDC consumption of the vehicle expressed in $$\mathrm{gCO\_2/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 $$\mathrm{CO\_2}$$ emission « co2Emission » and the function below:

![Energy class definition](https://lh3.googleusercontent.com/o7zeQ4fozZs6TYCtPglmJlV-zaQ2cmq_qNLKyJsWbV-MkL-_s6lJj_l1J0evkI1qXekhyWly4xZX6TlofZw_-i8K9PY6aN801sW2v8xhJIH-csAkJJ4n6j9AOn_1V4G3guE-BdI2)

### Advanced eco-driving

<table><thead><tr><th width="193">Field</th><th width="168.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>ecoDrivingContext</td><td><code>array[object]</code></td><td>Array of <a href="#ecodrivingcontext">EcoDrivingContext</a></td></tr></tbody></table>

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

{% hint style="warning" %}
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.
{% endhint %}

#### EcoDrivingContext

<table><thead><tr><th width="174">Field</th><th width="121.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>distance</td><td><code>double</code></td><td>Percentage of distance travelled in a road type</td></tr><tr><td>duration</td><td><code>double</code></td><td>Percentage of elapsed time in a road type</td></tr><tr><td>efficiencyScore</td><td><code>double</code></td><td>Eco-driving score</td></tr><tr><td>scoreAccel</td><td><code>double</code></td><td>Score of the acceleration phases</td></tr><tr><td>scoreMain</td><td><code>double</code></td><td>Score of the stabilized speed phases</td></tr><tr><td>scoreDecel</td><td><code>double</code></td><td>Score of the deceleration phases</td></tr><tr><td>contextId</td><td><code>int</code></td><td><a href="/pages/-LnIYWt8LUcTbp4cVirZ#road-conditions">Road conditions</a></td></tr></tbody></table>

### 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:

<table><thead><tr><th width="153">Fuel type</th><th width="138">Density (kg/l)</th><th>Lower heating value (GJ/t)</th><th>CO2 emission factor (tCO2/TJ)</th><th>CO2 emission factor (kgCO2/l)</th></tr></thead><tbody><tr><td>Gasoline</td><td>0.755</td><td>44</td><td>70.26</td><td>2.3340</td></tr><tr><td>Diesel</td><td>0.845</td><td>42</td><td>75.70</td><td>2.6866</td></tr></tbody></table>

Values calculated by fuel estimation module are described below:

<table><thead><tr><th width="215">Field</th><th width="114.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>co2Mass</td><td><code>double</code></td><td>Total Mass of <span class="math">\mathrm{CO_2}</span> in kg</td></tr><tr><td>co2Emission</td><td><code>double</code></td><td>Average Mass of <span class="math">\mathrm{CO_2}</span> per unit of distance in g/km</td></tr><tr><td>fuelConsumption</td><td><code>double</code></td><td>Average fuel consumption per unit of distance in l/100km</td></tr><tr><td>fuelVolume</td><td><code>double</code></td><td>Total fuel consumption in liter</td></tr><tr><td>idleFuelPercentage</td><td><code>double</code></td><td>Idle fuel consumption percentage</td></tr><tr><td>idleFuelConsumption</td><td><code>double</code></td><td>Idle fuel consumption per unit of time in l/h</td></tr><tr><td>idleCo2Emission</td><td><code>double</code></td><td>Idle <span class="math">\mathrm{CO_2}</span> emission in g/km</td></tr><tr><td>idleCo2Mass</td><td><code>double</code></td><td>Idle <span class="math">\mathrm{CO_2}</span> mass in kg</td></tr><tr><td>engineTempStatus</td><td><code>boolean</code></td><td>Engine cold start?</td></tr><tr><td>coldFuelVolume</td><td><code>double</code></td><td>Cold engine fuel volume</td></tr></tbody></table>

### Advanced fuel estimation

<table><thead><tr><th width="216">Field</th><th width="182.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>fuelEstimationContext</td><td><code>array[object]</code></td><td>Array of <a href="/pages/-LmyNRA_muNPJIeFBcbX#fuelestimationcontext">FuelEstimationContext</a></td></tr></tbody></table>

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):&#x20;

* 0 - Traffic jam
* 1 - Heavy urban traffic
* 2 - City
* 3 - Suburban
* 4 - Expressways

{% hint style="warning" %}
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.
{% endhint %}

#### FuelEstimationContext

<table><thead><tr><th width="182.66666666666666">Field</th><th width="120">Type</th><th>Description</th></tr></thead><tbody><tr><td>contextId</td><td><code>int</code></td><td>Road conditions</td></tr><tr><td>distance</td><td><code>double</code></td><td>Percentage of distance travelled in a road type</td></tr><tr><td>duration</td><td><code>double</code></td><td>Percentage of elapsed time in a road type</td></tr><tr><td>co2Mass</td><td><code>double</code></td><td>Total Mass of  <span class="math">\mathrm{CO_2}</span> in kg</td></tr><tr><td>co2Emission</td><td><code>double</code></td><td>Average <span class="math">\mathrm{CO_2}</span> emissions in g/km</td></tr><tr><td>fuelVolume</td><td><code>double</code></td><td>Total fuel consumption in liter</td></tr><tr><td>fuelConsumption</td><td><code>double</code></td><td>Average fuel consumption in l/100km</td></tr></tbody></table>

### **EnergyEstimation**

For electric vehicles, DriveQuant provides energy information instead of fuel estimation.

<table><thead><tr><th width="242">Field</th><th width="99.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>energy</td><td><code>double</code></td><td>Estimated energy in kWh</td></tr><tr><td>energyConsumption</td><td><code>double</code></td><td>Estimated energy consumption in kWh/100km</td></tr><tr><td>energyOpti</td><td><code>double</code></td><td>Optimal energy in kWh</td></tr><tr><td>energyOptiConsumption</td><td><code>double</code></td><td>Optimal energy consumption in kWh/100km</td></tr></tbody></table>

{% hint style="info" %}
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.
{% endhint %}

### **AdvancedEnergyEstimation**

To provide more details on the energy consumption, the service may return the energy data for each driving context of the vehicle.

<table><thead><tr><th width="243.66666666666666">Field</th><th width="117">Type</th><th>Description</th></tr></thead><tbody><tr><td>energy</td><td><code>double</code></td><td>Estimated energy in kWh</td></tr><tr><td>energyConsumption</td><td><code>double</code></td><td>Estimated energy consumption in kWh/100km</td></tr><tr><td>energyOpti</td><td><code>double</code></td><td>Optimal energy in kWh</td></tr><tr><td>energyOptiConsumption</td><td><code>double</code></td><td>Optimal energy in kWh/100km</td></tr><tr><td>contextId</td><td><code>int</code></td><td>Road conditions</td></tr><tr><td>distance</td><td><code>double</code></td><td>Percentage of distance travelled in a road type</td></tr><tr><td>duration</td><td><code>double</code></td><td>Percentage of elapsed time in a road type</td></tr></tbody></table>

{% hint style="info" %}
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.
{% endhint %}

### Safety

<table><thead><tr><th width="178">Field</th><th width="117.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>safetyScore</td><td><code>double</code></td><td><p>Driver risk index for a given itinerary</p><p>Ranges from 3 to 10</p></td></tr><tr><td>nbAdh</td><td><code>int</code></td><td>Number of adherence threshold crossing</td></tr><tr><td>nbAccel</td><td><code>int</code></td><td>Number of strong accelerations</td></tr><tr><td>nbDecel</td><td><code>int</code></td><td>Number of strong decelerations</td></tr><tr><td>nbAdhCrit</td><td><code>int</code></td><td>Number of adherence threshold crossing (critical)</td></tr><tr><td>nbAccelCrit</td><td><code>int</code></td><td>Number of critical accelerations (critical)</td></tr><tr><td>nbDecelCrit</td><td><code>int</code></td><td>Number of critical decelerations (critical)</td></tr></tbody></table>

{% hint style="warning" %}
&#x20;If trip is too short to be scored, `safetyScore` is set to 11.
{% endhint %}

### Advanced safety

| Field         | Type            | Description                                                               |
| ------------- | --------------- | ------------------------------------------------------------------------- |
| safetyContext | `array[object]` | Array of [SafetyContext](/trip-analysis/rest-services/trip#safetycontext) |

#### SafetyContext

<table><thead><tr><th width="164.66666666666666">Field</th><th width="113">Type</th><th>Percentage of distance travelled in a road type</th></tr></thead><tbody><tr><td>distance</td><td><code>double</code></td><td>Percentage of distance travelled in a road type</td></tr><tr><td>duration</td><td><code>double</code></td><td>Percentage of elapsed time in a road type</td></tr><tr><td>safetyScore</td><td><code>double</code></td><td>Ranges from 3 to 10</td></tr><tr><td>nbAdh</td><td><code>int</code></td><td>Number of adherence threshold crossing</td></tr><tr><td>nbAccel</td><td><code>int</code></td><td>Number of strong accelerations</td></tr><tr><td>nbDecel</td><td><code>int</code></td><td>Number of strong decelerations</td></tr><tr><td>nbAdhCrit</td><td><code>int</code></td><td>Number of adherence threshold crossing (critical)</td></tr><tr><td>nbAccelCrit</td><td><code>int</code></td><td>Number of critical accelerations (critical)</td></tr><tr><td>nbDecelCrit</td><td><code>int</code></td><td>Number of critical decelerations (critical)</td></tr><tr><td>contextId</td><td><code>int</code></td><td>Road conditions</td></tr></tbody></table>

{% hint style="warning" %}
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.
{% endhint %}

### 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.

<table><thead><tr><th width="136.66666666666666">Field</th><th width="116">Type</th><th>Description</th></tr></thead><tbody><tr><td>time</td><td><code>double</code></td><td>Time since the beginning of the trip in second</td></tr><tr><td>latitude</td><td><code>double</code></td><td>Latitude in degree</td></tr><tr><td>longitude</td><td><code>double</code></td><td>Longitude in degree</td></tr><tr><td>velocity</td><td><code>double</code></td><td>Vehicle speed in km/h</td></tr><tr><td>heading</td><td><code>double</code></td><td>Vehicle heading in degree</td></tr><tr><td>elevation</td><td><code>double</code></td><td>Altitude in meter</td></tr><tr><td>distance</td><td><code>double</code></td><td>Distance travelled since the beginning of the trip in meter</td></tr><tr><td>type</td><td><code>int</code></td><td>Type of event<br>    1. Adherence<br>    2. Acceleration<br>    3. Braking</td></tr><tr><td>level</td><td><code>int</code></td><td>Intensity related to the event<br>    1. Strong<br>    2. Harsh</td></tr><tr><td>value</td><td><code>int</code></td><td><p>Absolute value of the event:</p><ul><li>in m/s2 for acceleration and braking events</li><li>normalized between 0 and 1 for the adherence events</li></ul></td></tr></tbody></table>

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.

<table><thead><tr><th>Type of event</th><th width="98">Unit</th><th width="101">Strong</th><th>Harsh</th></tr></thead><tbody><tr><td>Acceleration </td><td>m/s2</td><td>2.0</td><td>2.5</td></tr><tr><td>Braking</td><td>m/s2</td><td>-1.8</td><td>-2.4</td></tr><tr><td>Adherence limit</td><td>-</td><td>0.2</td><td>0.3</td></tr></tbody></table>

### Pollutants

<table><thead><tr><th width="106.66666666666666">Field</th><th width="117">Type</th><th>Description</th></tr></thead><tbody><tr><td>co</td><td><code>double</code></td><td>Carbon monoxide (CO) emissions expressed in mg/km</td></tr><tr><td>hc</td><td><code>double</code></td><td>Hydrocarbons (HC) emissions expressed in mg/km</td></tr><tr><td>nox</td><td><code>double</code></td><td>Nitrogen oxide emissions (NOx) expressed in mg/km</td></tr><tr><td>soot</td><td><code>double</code></td><td>Soot emissions expressed in mg/km</td></tr></tbody></table>

### 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.&#x20;

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).&#x20;

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:&#x20;

* 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 = $$10^9$$ppb. 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 ($$10^9$$ppb) 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:&#x20;

Assuming a vehicle that has performed $$N$$ trips, the tire autonomy ( $$d\_a$$ ) in km can be computed as follow:

$$d\_a=f(w)\times\sum\_{k=1}^Nd\_i$$ with $$f(w)=\frac{1}{10^9\times\sum\_{k=1}^Nw\_i}-1$$&#x20;

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:

![](https://lh5.googleusercontent.com/zEF2xgPIxXRY9o34GjFjsHqdYeRMw47MlYGe-El9YmDiOnF-z8-TMgdU2q_OVwNKSA9hBlbodW5Mo3pI2TBQyUiU6ow5AlK98XR-NpGDPJcUjR6s43Nki0KR7QyrPbsFHUZ0X-R5)

**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.

![](https://lh5.googleusercontent.com/KrfZ8VA8u4gGW4PKsWnW8qQ6PSv_VzpCGIXHMdKU8W-kcr_0-vRoSjG1R9IoYaDKm2oC9mptpFvRKASmGvId5GEjWqjiXyaJVPrkLdRFKvdthTIhbXreWgDL9qDSIPkz01kMJKaW)

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.

<table><thead><tr><th width="210.66666666666666">Field</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td>frontTireWear</td><td><code>int</code></td><td><p>Worn mass fraction of the front tires (right/ left) for current trip</p><p>Unit : thousandths part of ppm = ppb</p><p>Min. value = 0 / Max. value = <span class="math">10^9</span> </p></td></tr><tr><td>rearTireWear</td><td><code>int</code></td><td><p>Worn mass fraction of the rear tires (right/left) for current trip</p><p>Unit : thousandths part of ppm = ppb</p><p>Min. value = 0 / Max. value = <span class="math">10^9</span></p></td></tr><tr><td>frontBrakePadWear</td><td><code>int</code></td><td><p>Worn mass fraction of the front brakes (right/left) for current trip</p><p>Unit : thousandths part of ppm = ppb</p><p>Min. value = 0 / Max. value = <span class="math">10^9</span> </p></td></tr><tr><td>rearBrakePadWear</td><td><code>int</code></td><td><p>Worn mass fraction of the rear brakes (right/left) for current trip</p><p>Unit : thousandths part of ppm = ppb</p><p>Min. value = 0 / Max. value = <span class="math">10^9</span> </p></td></tr><tr><td>frontTireDistance</td><td><code>int</code></td><td><p>Total distance analyzed for the front tires (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>rearTireDistance</td><td><code>int</code></td><td><p>Total distance analyzed for the rear tires (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>frontBrakeDistance</td><td><code>int</code></td><td><p>Total distance analyzed for the front brakes (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>rearBrakeDistance</td><td><code>int</code></td><td><p>Total distance analyzed for the rear brakes (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>frontTireAutonomy</td><td><code>int</code></td><td><p>Front tires remaining distance before change (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>rearTireAutonomy</td><td><code>int</code></td><td><p>Rear tires remaining distance before change (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>frontBrakeAutonomy</td><td><code>int</code></td><td><p>Front brakes remaining distance before change (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>rearBrakeAutonomy</td><td><code>int</code></td><td><p>Rear brakes remaining distance before change (in km)</p><p>Min. value = 0 / Max. value = 1 000 000</p></td></tr><tr><td>frontTireTotalWear</td><td><code>double</code></td><td><p>Total worn mass percentage of the front tires (right/left) </p><p>Min. value = 0% / Max. value = 100%</p></td></tr><tr><td>rearTireTotalWear</td><td><code>double</code></td><td><p>Total worn mass percentage of the rear tires (right/left) </p><p>Min. value = 0% / Max. value = 100%</p></td></tr><tr><td>frontBrakeTotalWear</td><td><code>double</code></td><td><p>Total worn mass percentage of the front brakes (right/left) </p><p>Min. value = 0% / Max. value = 100%</p></td></tr><tr><td>rearBrakeTotalWear</td><td><code>double</code></td><td><p>Total worn mass percentage of the rear brakes (right/left) </p><p>Min. value = 0% / Max. value = 100%</p></td></tr><tr><td>frontTireWearRate</td><td><code>double</code></td><td>Average wear rate for the front tires (in %/1000 km )</td></tr><tr><td>rearTireWearRate</td><td><code>double</code></td><td>Average wear rate for the rear tires (in %/1000 km )</td></tr><tr><td>frontBrakeWearRate</td><td><code>double</code></td><td>Average wear rate for the rear brakes (in %/1000 km )</td></tr><tr><td>rearBrakeWearRate</td><td><code>double</code></td><td>Average wear rate for the rear brakes (in %/1000 km )</td></tr></tbody></table>

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:&#x20;

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.

<figure><img src="/files/sjmZH9lgznPh09DfGod6" alt="" width="563"><figcaption></figcaption></figure>

The sensitivity function linking the call duration to the call score is shown below.

<img src="/files/EpCt8eqELHav8C2s6RoR" alt="" width="563">

{% hint style="info" %}
This service is only available with the DriveKit mobile SDK.
{% endhint %}

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:

<table><thead><tr><th width="155.66666666666666">Field</th><th width="170">Type</th><th>Description</th></tr></thead><tbody><tr><td>nbUnlock</td><td><code>int</code></td><td>Number of phone screen unlock events</td></tr><tr><td>nbLock</td><td><code>int</code></td><td>Number of phone screen lock events</td></tr><tr><td>distance</td><td><code>double</code> </td><td>Relative distance traveled with the screen on (in %)</td></tr><tr><td>distanceM</td><td><code>double</code></td><td>Distance traveled with the screen on (in m)</td></tr><tr><td>duration</td><td><code>double</code></td><td>Relative duration traveled with the screen on (in %)</td></tr><tr><td>durationS</td><td><code>double</code></td><td>Duration traveled with the screen on (in s)</td></tr><tr><td>score</td><td><code>double</code></td><td>Phone distraction score (Min. value = 0, Max. value = 10)</td></tr><tr><td>scoreUnlock</td><td><code>double</code></td><td>Distraction sub-score which takes into account the number of locking/unlocking</td></tr><tr><td>scoreCall</td><td><code>double</code></td><td>Distraction sub-score which takes into account the number of calls during the trip</td></tr><tr><td>calls</td><td><code>array[object]</code></td><td><a href="#call">Call</a></td></tr></tbody></table>

#### 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.

<table><thead><tr><th width="155.66666666666666">Value</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td><code>int</code></td><td>Unique identifier of the call</td></tr><tr><td>start</td><td><code>double</code></td><td>Seconds from beginning of the trip when call starts</td></tr><tr><td>end</td><td><code>double</code></td><td>Seconds from beginning of the trip when call ends</td></tr><tr><td>durationS</td><td><code>double</code></td><td>Duration traveled in call (in s)</td></tr><tr><td>duration</td><td><code>double</code></td><td>Relative duration traveled in call (in %)</td></tr><tr><td>distanceM</td><td><code>double</code></td><td>Distance traveled in call (in m)</td></tr><tr><td>distance</td><td><code>double</code></td><td>Relative distance traveled in call (in %)</td></tr><tr><td>status</td><td><code>string</code></td><td><p>INCOMING : incoming call</p><p>OUTGOING : outgoing call</p><p>UNKNOWN : unknown call status</p></td></tr><tr><td>audioSystem</td><td><code>string</code></td><td>Audio system used to make the call (SPEAKER, LOUDSPEAKER, A2DP, HANDSFREE, HEADPHONE, CAR_AUDIO, UNKNOWN)</td></tr><tr><td>forbidden</td><td><code>boolean</code></td><td><p><code>true</code> if the call is forbidden</p><p><code>false</code> if the call is authorized (made with handsfree)</p></td></tr></tbody></table>

#### Response body example

<pre class="language-javascript"><code class="lang-javascript">"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
<strong>      },
</strong>      {
        "id": 1,
        "start": 320,
        "end": 344,
        "durationS": 24,
        "duration": 5,
        "distanceM": 295,
        "distance": 4,
        "status": "UNKNOWN",
        "audioSystem": "HANDSFREE",
        "forbidden": false
      }
    ]
  }
</code></pre>

#### &#x20;Example of use

The screenshot below shows how to display the phone use data on a mobile phone interface:

![](/files/-MUy-uxsjd1WZNEBtsqR)

### 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:

<table><thead><tr><th width="140.66666666666666">Field</th><th width="116">Type</th><th>Description</th></tr></thead><tbody><tr><td>time</td><td><code>double</code></td><td>Time since the beginning of the trip (in s)</td></tr><tr><td>latitude</td><td><code>double</code></td><td>Latitude (in deg)</td></tr><tr><td>longitude</td><td><code>double</code></td><td>Longitude (in deg)</td></tr><tr><td>velocity</td><td><code>double</code></td><td>Vehicle speed (in km/h)</td></tr><tr><td>heading</td><td><code>double</code></td><td>Vehicle heading (in deg)</td></tr><tr><td>elevation</td><td><code>double</code></td><td>Altitude (in m)</td></tr><tr><td>distance</td><td><code>double</code></td><td>Distance travelled since the beginning of the trip (in m)</td></tr><tr><td>type</td><td><code>int</code></td><td>Type of event : (1) Screen ON and (2) Screen OFF</td></tr></tbody></table>

#### Response body example

```javascript
"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).

<table><thead><tr><th width="149.66666666666666">Value</th><th width="112">Type</th><th>Description</th></tr></thead><tbody><tr><td>time</td><td><code>double</code></td><td>Time in second since the beginning of the trip</td></tr><tr><td>latitude</td><td><code>double</code></td><td>Latitude in degree</td></tr><tr><td>longitude</td><td><code>double</code></td><td>Longitude  in degree</td></tr><tr><td>velocity</td><td><code>double</code></td><td>Vehicle speed in km/h</td></tr><tr><td>heading</td><td><code>double</code></td><td>Vehicle heading in degree</td></tr><tr><td>elevation</td><td><code>double</code></td><td>Altitude in meter</td></tr><tr><td>distance</td><td><code>double</code></td><td>Distance travelled during the call in meter</td></tr><tr><td>type</td><td><code>int</code></td><td><p>3: Call start</p><p>4: Call end</p></td></tr><tr><td>duration</td><td><code>int</code></td><td>Call duration in seconds</td></tr><tr><td>index</td><td><code>int</code></td><td>Position of the beginning of the event  in the route date (phone call beginning of phone unlocking)</td></tr><tr><td>audioSystem</td><td><code>string</code></td><td>Audio system used to make the call (<code>SPEAKER</code>, <code>LOUDSPEAKER</code>, <code>A2DP</code>, <code>HANDSFREE</code>, <code>HEADPHONE</code>, <code>CAR_AUDIO</code>, <code>UNKNOWN</code>)</td></tr><tr><td>callType </td><td><code>string</code></td><td><p>Call type</p><p>Allowed values: <code>INCOMING</code>, <code>OUTGOING</code>, <code>UNKNOWN</code></p></td></tr><tr><td>forbidden</td><td><code>boolean</code></td><td><p><code>true</code> if the call is forbidden</p><p><code>false</code> if the call  is authorized (made with handsfree)</p></td></tr></tbody></table>

#### Response body example

```javascript
"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.

<figure><img src="/files/ilziPs511TDY7H9WYfZd" alt="" width="563"><figcaption><p>Log scale sensitivity function for speeding score</p></figcaption></figure>

<figure><img src="/files/ObL7aKq1lVtbuzh6Zfak" alt="" width="563"><figcaption><p>Speed score sensitivity function in decimal scale</p></figcaption></figure>

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.&#x20;

The global (or trip) score is the average of the sub-scores weighted by distance.

<table><thead><tr><th width="200.66666666666666">Field</th><th width="168">Type</th><th>Description</th></tr></thead><tbody><tr><td>distance</td><td><code>int</code></td><td>trip distance (m)</td></tr><tr><td>duration</td><td><code>int</code></td><td>trip duration (s)</td></tr><tr><td>speedingDistance</td><td><code>int</code></td><td>Distance travelled at a speed above the limit (m)</td></tr><tr><td>speedingDuration</td><td><code>int</code></td><td>Duration spent at a speed above the limit (s)</td></tr><tr><td>score</td><td><code>double</code></td><td>Speeding score</td></tr><tr><td>speedLimitContexts</td><td><code>array[object]</code></td><td>Array of <a href="/pages/-LmyNRA_muNPJIeFBcbX#speedlimitcontexts">SpeedLimitContexts</a></td></tr></tbody></table>

#### SpeedLimitContexts

<table><thead><tr><th width="195">Field</th><th width="106.66666666666666">Type</th><th>Description</th></tr></thead><tbody><tr><td>speedLimit</td><td><code>int</code></td><td>Speed limit (in km/h) for the portion of the trip</td></tr><tr><td>distance</td><td><code>int</code></td><td>Total distance (in m) for the portion of the trip limited at the speed limit value</td></tr><tr><td>duration</td><td><code>int</code></td><td>Total duration (in s) for the portion of the trip limited at the speed limit value</td></tr><tr><td>speedingDistance</td><td><code>int</code></td><td>Distance travelled at a speed above the limit (in m) within the speed limit portion</td></tr><tr><td>speedingDuration</td><td><code>int</code></td><td>Duration spent at a speed above the limit (in s) within the speed limit portion</td></tr><tr><td>score</td><td><code>double</code></td><td>Speeding score for a given speed limit portion </td></tr></tbody></table>

#### Response body example

```javascript
{
"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.&#x20;

The start and end positions of overspeeding segments are included in the SpeedingEvents table.

<table><thead><tr><th width="132.66666666666666">Value</th><th width="116">Type</th><th>Description</th></tr></thead><tbody><tr><td>time</td><td><code>double</code></td><td>Time in second since the beginning of the trip</td></tr><tr><td>latitude</td><td><code>double</code></td><td>Latitude in degree</td></tr><tr><td>longitude</td><td><code>double</code></td><td>Longitude in degree</td></tr><tr><td>type</td><td><code>int</code></td><td><p>1 = Overspeeding segment start point</p><p>0 = Overspeeding segment endpoint</p></td></tr><tr><td>index</td><td><code>int</code></td><td>Index of the speeding event in the matched route vector.</td></tr></tbody></table>

**Response body example**

```javascript
"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
    }
]
```


# References

This section describes the main response codes of the trip analysis API.

## Vehicle body type

| Value | Type  | Description        |
| ----- | ----- | ------------------ |
| 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     |

## Engine type

| Value | Description                 |
| ----- | --------------------------- |
| 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                    |

## Gearbox type

| Value | Description    |
| ----- | -------------- |
| 1     | Automatic      |
| 2     | Manual 5-speed |
| 3     | Manual 6-speed |
| 4     | Manual 7-speed |
| 5     | Manual 8-speed |

## Drive wheels type

| Value | Description       |
| ----- | ----------------- |
| 0     | Front-wheel drive |
| 1     | Rear-wheel drive  |
| 2     | Four-wheel drive  |

## Weather code

| Value | Description |
| ----- | ----------- |
| 0     | Unknown     |
| 1     | Clear sky   |
| 2     | Cloudy      |
| 3     | Foggy       |
| 4     | Rainy       |
| 5     | Snowy       |
| 6     | Icy         |

## Transportation Mode

| Value | Description        |
| ----- | ------------------ |
| 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              |

## Road conditions

<table><thead><tr><th width="81.66666666666666">Value</th><th>Description</th><th>Comment</th></tr></thead><tbody><tr><td>0</td><td>Traffic jam</td><td>This corresponds to vehicle displacements of less than 100 meters and performed with speeds below 10 km/h</td></tr><tr><td>1</td><td>Heavy urban traffic</td><td>Speed below 30 km/h and distance between two stops greater than 100 m</td></tr><tr><td>2</td><td>City</td><td>30 km/h &#x3C; Speed &#x3C; 65 km/h</td></tr><tr><td>3</td><td>Suburban</td><td>65 km/h &#x3C; Speed &#x3C; 96 km/h</td></tr><tr><td>4</td><td>Expressways</td><td>Speed > 96 km/h</td></tr></tbody></table>

## Error codes

<table><thead><tr><th width="137">Status</th><th width="76">Code</th><th>Comment</th><th>Description</th></tr></thead><tbody><tr><td><code>true</code></td><td>0</td><td> OK</td><td>The data are correct and the process ran fine</td></tr><tr><td><code>false</code></td><td>10</td><td>Mandatory account object not found</td><td>The « account» block is not set</td></tr><tr><td><code>false</code></td><td>13</td><td>Mandatory route object not found</td><td>The « route » block is not available → The trip analysis is not possible</td></tr><tr><td><code>false</code></td><td>14</td><td>Invalid route definition</td><td>Error when parsing the Route block</td></tr><tr><td><code>false</code></td><td>15</td><td>Velocity data is missing</td><td>The vehicle or GPS velocity is not available → The trip analysis is not possible</td></tr><tr><td><code>true</code></td><td>16</td><td>Engine speed not available</td><td>The engine speed is not available → The trip analysis is performed with an estimated value of the engine speed</td></tr><tr><td><code>true</code></td><td>17</td><td>Engine speed is null</td><td>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</td></tr><tr><td><code>true</code></td><td>18</td><td>One or more vehicle parameters are missing (&#x3C;list of missing parameters>). Default values are used</td><td>The vehicle characteristics are not set or some values are missing → The trip analysis is performed with generic vehicle model parameters</td></tr><tr><td><code>false</code></td><td>19</td><td>Invalid sampling period: one second recording interval is recommended for input variables</td><td>The input variables have an invalid acquisition period → The trip analysis is not possible</td></tr><tr><td><code>true</code></td><td>20</td><td>More than 25% of data loss</td><td>More than 25% of data loss is detected during the trip</td></tr><tr><td><code>false</code></td><td>21</td><td>Invalid customerId</td><td>Unknown account value. Unauthorized access.</td></tr><tr><td><code>false</code></td><td>23</td><td>Date data is missing</td><td>The field vehicleDate or gpsDate is not available → The trip analysis is not possible</td></tr><tr><td><code>false</code></td><td>24</td><td>Daily request number is reached</td><td>The maximum daily request number is reached</td></tr><tr><td><code>true</code></td><td>25</td><td>The trip distance is lower than 1 km</td><td>This error message indicates that the trip was analysed but the distance is not sufficient to provide an accurate energy analysis</td></tr><tr><td><code>false</code></td><td>26</td><td>Your request could not be processed. If the problem persist, please contact us</td><td>The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem</td></tr><tr><td><code>false</code></td><td>27</td><td>Your request could not be processed. If the problem persist, please contact us</td><td>The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem</td></tr><tr><td><code>true</code></td><td>28</td><td>One or more vehicle parameters are out of bound (&#x3C;list of missing parameters>)</td><td>The vehicle characteristics are not in the range of available values. See vehicle characteristics for range limits</td></tr><tr><td><code>false</code></td><td>29</td><td>Beacon is missing</td><td>The beacon has not been detected and it is required to validate the trip analysis</td></tr><tr><td><code>false</code></td><td>30</td><td>Invalid beacon  data</td><td>A beacon was detected during the trip but it does not have the correct identifiers</td></tr><tr><td><code>false</code></td><td>31</td><td>A similar trip has already been processed and stored with same account</td><td>The duplicate trip feature is enabled and the trip has already been analyzed</td></tr><tr><td><code>true</code></td><td>32</td><td>The vehicleId is invalid</td><td>No vehicle found for the vehicleId provided into the API request</td></tr><tr><td><code>false</code></td><td>33</td><td>The total of GPS points are under 10</td><td>There is not enough GPS points to perform an analysis</td></tr><tr><td><code>false</code></td><td>34</td><td>The account of this driver is disabled</td><td>The driver account is disabled</td></tr><tr><td><code>false</code></td><td>35</td><td>The automatic driver account creation is disabled</td><td>The automatic creation is disabled, use a valid authentication process to create the driver account</td></tr><tr><td><code>false</code></td><td>36</td><td>All the dates are negatives</td><td>The field vehicleDate or gpsDate contains negative values → The trip analysis is not possible</td></tr><tr><td><code>false</code></td><td>37</td><td>Your request could not be processed. If the problem persist, please contact us</td><td>The service failed to process your data. There is a need to diagnose your data to determine the origin of this problem</td></tr><tr><td><code>false</code></td><td>38</td><td>Unable to create a new driver: maximum number of drivers reached for the account</td><td>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.</td></tr></tbody></table>


# Trip Simulator

To verify the DriveKit Trip Analysis component integration into your app, it is recommended to perform tests in real conditions. &#x20;

Before carrying out driving tests, it may be useful to validate the implementation of the SDK in your application.&#x20;

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:&#x20;

* 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.

{% hint style="info" %}
You can try the Trip Simulator feature in the [DriveKit Demo App](/#the-drivekit-demo-app).
{% endhint %}


# iOS

## Integration

The Trip Simulator component includes two modules:&#x20;

* 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:

* **Swift Package Manager:** Add '`DriveKitTripSimulator`' from repository: `https://github.com/DriveQuantPublic/drivekit-sdk-spm.git` as dependency and '`DriveKitTripSimulatorNoop`' module in release if you need it.
* **Cocoapods** (deprecation scheduled for the end of 2025): add the following lines to your dependencies in your Podfile, with the no-op module in release mode if you need it:

```swift
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.

<table data-header-hidden><thead><tr><th width="298.71428571428567">Name</th><th width="120">Duration (s)</th><th width="126">Distance (m)</th><th>Description</th></tr></thead><tbody><tr><td>Name</td><td>Duration</td><td>Distance</td><td>Description</td></tr><tr><td><code>shortTrip</code> </td><td>8 min</td><td>2 km</td><td>Trip too short that does not allow to rate the driver's behavior</td></tr><tr><td><code>mixedTrip</code> </td><td>15 min</td><td>12 km</td><td>A 15-minute mixed trip in urban and suburban areas</td></tr><tr><td><code>cityTrip</code> </td><td>20 min</td><td>8 km</td><td>A 20-minute city trip </td></tr><tr><td><code>suburbanTrip</code> </td><td>30 min</td><td>30 km</td><td>A 30-minute trip performed in a suburban environment mostly</td></tr><tr><td><code>highwayTrip</code> </td><td>55 min</td><td>100 km</td><td>A 55-minute highway trip </td></tr><tr><td><code>trainTrip</code> </td><td>10 min</td><td>5 km</td><td>Trip recorded in a train to test the alternative transportation modes detection</td></tr><tr><td><code>busTrip</code></td><td>13 min</td><td>3 km</td><td>Trip recorded in a bus to test the alternative transportation modes detection</td></tr><tr><td><code>boatTrip</code></td><td>40 min</td><td>25 km</td><td>Trip recorded in a boat to test the alternative transportation modes detection</td></tr><tr><td><code>tripWithCrash</code></td><td>5 min</td><td>1 km</td><td>A trip to simulate an unconfirmed or a confirmed crash.</td></tr><tr><td><code>tripWithCrashStillDriving</code></td><td>23 min</td><td>24 km</td><td>A trip to simulate an accident confirmed less than two minutes after the start of the trip, after which the driver continued driving.</td></tr></tbody></table>

### Check if it’s the no-op module

To verify if you are embedding the no-op module, you can call the following code:

```swift
let isNoop = DriveKitTripSimulator.shared.isNoop
```

### **Simulate a trip**

To simulate a trip, you just need to send the selected trip to the `start` method:

```swift
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:

```swift
import DriveKitTripSimulatorModule

DriveKitTripSimulator.shared.stop()
```

### Simulate a crash during a trip

{% hint style="warning" %}
The simulation of a trip with a collision only works on a real device, not with the simulator.
{% endhint %}

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:

<table><thead><tr><th width="179.78978549715043">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>confirmed40KmH</code></td><td>A short trip with a collision at 40 km/h that occurs 132 seconds after the trip begins and that corresponds to a confirmed accident.</td></tr><tr><td><code>confirmed30KmH</code></td><td>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.</td></tr><tr><td><code>confirmed20KmH</code></td><td>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.</td></tr><tr><td><code>unconfirmed0KmH</code></td><td>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.</td></tr><tr><td><code>confirmed30KmHStillDriving</code></td><td>A trip to with a collision at 30km/h that occurs 95 seconds after the trip begins and that corresponds to a confirmed accident, after which the driver continue driving.</td></tr></tbody></table>

```swift
DriveKitTripSimulator.shared.startCrashTrip(.confirmed20KmH)
```


# 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:

```gradle
dependencies {
    debugImplementation 'com.drivequant.drivekit:drivekit-trip-simulator:$drivekit_version'
    releaseImplementation 'com.drivequant.drivekit:drivekit-trip-simulator-noop:$drivekit_version'
}
```

{% hint style="info" %}
Replace `$drivekit_version` with the DriveKit version you are using in your app
{% endhint %}

## 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.

<table><thead><tr><th width="247.5132933346892">Name</th><th width="107">Duration (min)</th><th width="86.70248040495565">Distance (km)</th><th>Description</th></tr></thead><tbody><tr><td>SHORT_TRIP</td><td>8</td><td>2</td><td>Trip too short that does not allow to rate the driver's behavior</td></tr><tr><td>MIXED_TRIP</td><td>15</td><td>12</td><td>A mixed trip in urban and suburban areas</td></tr><tr><td>CITY_TRIP</td><td>20</td><td>8</td><td>A city trip </td></tr><tr><td>SUBURBAN_TRIP</td><td>30</td><td>30</td><td>A trip performed in a suburban environment mostly</td></tr><tr><td>HIGHWAY_TRIP</td><td>55</td><td>100</td><td>A highway trip </td></tr><tr><td>TRAIN_TRIP</td><td>10</td><td>5</td><td>Trip recorded in a train to test the alternative transportation modes detection</td></tr><tr><td>BUS_TRIP</td><td>13</td><td>3</td><td>Trip recorded in a bus to test the alternative transportation modes detection</td></tr><tr><td>BOAT_TRIP</td><td>40</td><td>25</td><td>Trip recorded in a boat to test the alternative transportation modes detection</td></tr><tr><td>TRIP_WITH_CRASH_1</td><td>5</td><td>1</td><td>A trip to simulate an unconfirmed or a confirmed crash.</td></tr><tr><td>TRIP_WITH_CRASH_2_STILL_DRIVING</td><td>23</td><td>24</td><td>A trip to simulate an accident confirmed less than two minutes after the start of the trip, after which the driver continued driving.</td></tr></tbody></table>

### Enable Developer Mode

The user must enable the developer mode in Android. The [official documentation](https://developer.android.com/studio/debug/dev-options#enable) explains well how to proceed.

### 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.

{% tabs %}
{% tab title="DriveKitTripSimulator" %}

```kotlin
fun start(presetTrip: PresetTrip, listener: DKTripSimulatorListener? = null): Boolean
```

{% endtab %}
{% endtabs %}

### Stop the simulation

To stop the trip simulation, you must call the following metho&#x64;**:**

{% tabs %}
{% tab title="DriveKitTripSimulator" %}

```kotlin
fun stop()
```

{% endtab %}
{% endtabs %}

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:

<table><thead><tr><th width="275.09788437524355">Name</th><th>Description</th></tr></thead><tbody><tr><td>CONFIRMED_40KMH</td><td>A short trip with a collision at 40 km/h that occurs 132 seconds after the trip begins and that corresponds to a confirmed accident.</td></tr><tr><td>CONFIRMED_30KMH</td><td>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.</td></tr><tr><td>CONFIRMED_20KMH</td><td>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.</td></tr><tr><td>UNCONFIRMED_0KMH</td><td>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.</td></tr></tbody></table>

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitTripSimulator.start(PresetTrip.TRIP_WITH_CRASH_1(PresetTripCrash1.CONFIRMED_30KMH))
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitTripSimulator.INSTANCE.start(new PresetTrip.TRIP_WITH_CRASH_1(PresetTripCrash1.CONFIRMED_30KMH));
```

{% endtab %}
{% endtabs %}

### Check if it’s the no-op module <a href="#docs-internal-guid-119ea02b-7fff-c896-c348-46d5b787d500" id="docs-internal-guid-119ea02b-7fff-c896-c348-46d5b787d500"></a>

To check whether the "no-op" module is embedded, you can execute the following code:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val isNoop = DriveKitTripSimulator.isNoop
```

{% endtab %}

{% tab title="Java" %}

```java
final boolean isNoop = DriveKitTripSimulator.INSTANCE.isNoop();
```

{% endtab %}
{% endtabs %}


# 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.

<figure><img src="/files/Xa8KGSzeLf93Ci9VzB3g" alt=""><figcaption><p>Onboarding screens</p></figcaption></figure>

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.

<figure><img src="/files/QKRsFeDldpWEvZXuHnVg" alt=""><figcaption><p>Diagnostic screens</p></figcaption></figure>

{% hint style="info" %}
We recommend you to test this component in the [DriveKit Demo App](/#the-drivekit-demo-app) before you integrate it in your application.
{% endhint %}

<br>


# User interface


# iOS


# Get started

## **Prerequisite**   <a href="#prerequisite" id="prerequisite"></a>

Before starting DriveKit Permissions Utils UI integration, make sure that you have initialized [Common UI](https://docs.drivequant.com/common-ui/ios/get-started) module, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-core-module).

## **Integration** <a href="#integration" id="integration"></a>

The Permissions Utils UI SDK is available on Swift Package Manager.

{% hint style="info" %}
On a Github repository, you can find a demo app (for [iOS](https://github.com/DriveQuantPublic/drivekit-ui-ios) and [Android](https://github.com/DriveQuantPublic/drivekit-ui-android)) and the source code of Permissions Utils UI that you can use as an example.
{% endhint %}

### Swift Package Manager

#### Via Xcode:

* In Xcode, if not yet done, add the DriveKitUI SDK by navigating to File > Add Package Dependencies… and in the prompt that appears, enter the DriveKitUI repository:\
  `https://github.com/DriveQuantPublic/drivekit-ui-ios.git`&#x20;
* Include DriveKitPermissionsUtilsUI in your app.

#### Via Package.swift:

* If not yet done, to integrate DriveKitUI to a Swift package via a Package.swift file, you can add DriveKitUI to the dependencies array of your package. For more details, see the [Swift Package Manager documentation](https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html#package-dependency).

```swift
dependencies: [
  .package(name: "DriveKitUI",
           url: "https://github.com/DriveQuantPublic/drivekit-ui-ios.git",
           from: "2.0.0"),
  // ...
],
```

* Then in your target, add DriveKitPermissionsUtilsUI to the dependencies array of that target:

```swift
.target(
  name: "MyTarget",
  dependencies: [
    .product(name: "DriveKitPermissionsUtilsUI", package: "DriveKitUI"),
    // ...
  ]
),
```

## **Initialization**

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-core-module), the Permissions Utils UI module must also be manually initialized. In the application's AppDelegate file, import DriveKitPermissionsUtilsUI:

```swift
import DriveKitPermissionsUtilsUI
```

Then, to initialize the Permissions Utils module in your app, you must call the initialization method in didFinishLaunchingWithOptions method of your AppDelegate:

```swift
import DriveKitCoreModule
import DriveKitCommonUI
import DriveKitPermissionsUtilsUI

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   DriveKitUI.shared.initialize()
   DriveKitPermissionsUtilsUI.shared.initialize()
   ...
}
```


# 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:

```swift
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:

```swift
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:

```swift
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:&#x20;

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.

![Layout of the diagnosis screen on iOS](/files/JGf2G0hAmFsEjLvlrlWD)

The first two areas are always displayed. The third is optional.

The diagnosis function of the SDK has the following configurations:&#x20;

* 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.&#x20;
* 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.&#x20;

### **Support Request Management**

The user can make a support request if the application does not work properly.&#x20;

When the user clicks on the support request button, you can choose between two actions:&#x20;

1. An email will be automatically composed,&#x20;
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:

```swift
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:

```swift
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.<br>


# Android


# Get started

## **Prerequisite**

Before starting DriveKit Permissions Utils UI integration, make sure that you have initialized [Common UI](https://docs.drivequant.com/common-ui/android/get-started) module, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk).&#x20;

## Integration

To add the Permissions Utils UI module to your app, add the following line to your dependencies in your application build.gradle file:

{% tabs %}
{% tab title="build.gradle" %}

```gradle
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-permissions-utils-ui:$drivekitui_version'
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Replace `$drivekitui_version` with the DriveKit version you are using in your app
{% endhint %}

On a[ Github repository](https://github.com/DriveQuantPublic/drivekit-ui-android), you can find a demo app and the source code of Permissions Utils UI that you can use as an example.

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), the Permissions Utils UI module must also be manually initialized.

Then, to initialize the module in your app, you must call the initialization method in `onCreate` method of your Application class:

{% tabs %}
{% tab title="PermissionsUtilsUI" %}

```kotlin
fun initialize()
```

{% endtab %}
{% endtabs %}


# 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;&#x20;
* 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.&#x20;

Once all permissions have been granted by the user, you are warned by the closure passed in parameter:<br>

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
PermissionsUtilsUI.showPermissionViews(this, object : PermissionViewListener {
       override fun onFinish() {
          //Code called when all permissions in the list are properly granted
       }
   })
```

{% endtab %}

{% tab title="Java" %}

```java
PermissionsUtilsUI.INSTANCE.showPermissionViews(this, new PermissionViewListener() {
   @Override
   public void onFinish() {
       //Code called when all permissions in the list are properly granted
   }
});
```

{% endtab %}
{% endtabs %}

The Permissions Utils component automatically manages the permission request workflow depending on the version of Android installed on the user's smartphone.<br>

## **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:&#x20;

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.

![Layout of the diagnosis screen on Android](/files/182KZxsoaNEWID6NI1Eu)

The first two areas are always displayed. The third is optional.

The diagnostic function of the SDK has the following configurations:&#x20;

* 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.&#x20;
* Area 2 is always displayed if the Android version includes power-saving features (introduced from Android 6.0 - [API level 23](https://developer.android.com/training/monitoring-device-state/doze-standby)).
* 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitNavigationController.permissionsUtilsUIEntryPoint?.let {
   it.startAppDiagnosisActivity(this)
}
```

{% endtab %}

{% tab title="Java" %}

```java
PermissionsUtilsUIEntryPoint permissionsUtilsUIEntryPoint = DriveKitNavigationController.INSTANCE.getPermissionsUtilsUIEntryPoint();
if (permissionsUtilsUIEntryPoint != null) {
   permissionsUtilsUIEntryPoint.startAppDiagnosisActivity(this);
}
```

{% endtab %}
{% endtabs %}

### **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.&#x20;
2. To enable automatic start of trip recording from a Bluetooth device.

{% hint style="danger" %}
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.&#x20;
{% endhint %}

### **Support Request Management**

The user can make a support request if the application does not work properly.&#x20;

When the user clicks on the support request button, you can choose between two actions:&#x20;

1. An email will be automatically composed,&#x20;
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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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 
   }
})
```

{% endtab %}

{% tab title="Java" %}

```java
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
           }
       }
));
```

{% endtab %}
{% endtabs %}

If you want to redirect the user to a web page instead of composing an email, you have to add the following line:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
PermissionsUtilsUI.configureContactType(ContactType.WEB(Uri.parse("https://www.docs.drivequant.com")))
```

{% endtab %}

{% tab title="Java" %}

```java
PermissionsUtilsUI.INSTANCE.configureContactType(new ContactType.WEB(Uri.parse("https://www.docs.drivequant.com/")));
```

{% endtab %}
{% endtabs %}

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.

{% tabs %}
{% tab title="PermissionsUtilsUI" %}

```kotlin
fun configureContactType(contactType: ContactType)
```

{% endtab %}

{% tab title="Java" %}

```java
PermissionsUtilsUI.INSTANCE.configureContactType(ContactType.NONE.INSTANCE);
```

{% endtab %}
{% endtabs %}


# 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,&#x20;
* it avoids code duplicates.


# iOS


# Get started

## Integration

The Common UI SDK is a core configuration module for all DriveKit UI modules.

{% hint style="info" %}
On this[ Github repository](https://github.com/DriveQuantPublic/drivekit-ui-ios), you have a demo app and source code that you can use as an example.
{% endhint %}

To add the Common UI module to your app using **Swift Package Manager,** add `DriveKitCommonUI` from repository: `https://github.com/DriveQuantPublic/drivekit-ui-ios.git` as dependency.

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-core-module), 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.

```swift
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.

```swift
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:

```swift
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

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 [Github](https://github.com/DriveQuantPublic/drivekit-ui-ios), in the Localizable folder of each module.

```swift
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**

The translation file can be retrieved from [GitHub](https://github.com/DriveQuantPublic/drivekit-ui-ios). Add it to your application after adding the appropriate translation(s).

### 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:

```swift
DriveKitUI.shared.configureAnalytics(Analytics())
```

Where the Analytics object is for instance:

```swift
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.
    }
}
```

The `screen` String received in the `trackScreen` method is the value associated to one of the keys[ in this array](/common-ui/references), corresponding to the visited screen. If you want to customize screen tags, you can provide the path to a plist file (see the [default tags file](https://github.com/DriveQuantPublic/drivekit-ui-ios/blob/develop/DriveKitCommonUI/AnalyticsTags.plist)) with your custom values in the configuration method:

```swift
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.


# Android


# 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:

{% tabs %}
{% tab title="build.gradle" %}

<pre class="language-gradle"><code class="lang-gradle">dependencies {
<strong>    implementation 'com.drivequant.drivekit:drivekit-common-ui:$drivekitui_version'
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Replace `$drivekitui_version` with the DriveKit version you are using in your app
{% endhint %}

On a[ Github repository](https://github.com/DriveQuantPublic/drivekit-ui-android), you have a demo app and source code that you can use as an example.

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), 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.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class MyApplication: Application() {
    override fun onCreate() {
        super.onCreate()
        (…)
        DriveKitUI.initialize()
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class MyApplication extends Application {
   @Override
   public void onCreate() {
       super.onCreate();
       (…)
       DriveKitUI.initialize();
}}

```

{% endtab %}
{% endtabs %}

This method will initialize the SDK with the default configuration set up by DriveQuant.&#x20;

## **Configurations**

### **Colors**

The colors that can be configured are listed in the table below:

<table data-header-hidden><thead><tr><th width="306.3333333333333">Name</th><th width="283">Description</th><th>Default value</th></tr></thead><tbody><tr><td>Name</td><td>Description</td><td>Default value</td></tr><tr><td><code>primaryColor</code></td><td>Main app color</td><td>#0B4D6E</td></tr><tr><td><code>secondaryColor</code></td><td>Call to action color</td><td>#77E2B0</td></tr><tr><td><code>mainFontColor</code></td><td>Main font color</td><td>#161616</td></tr><tr><td><code>complementaryFontColor</code></td><td>Secondary font color</td><td>#9E9E9E</td></tr><tr><td><code>fontColorOnPrimaryColor</code></td><td>Color of a text displayed on an element whose color is <code>primaryColor</code></td><td>#FFFFFF</td></tr><tr><td><code>fontColorOnSecondaryColor</code></td><td>Color of a text displayed on an element whose color is <code>secondaryColor</code></td><td>#FFFFFF</td></tr><tr><td><code>backgroundViewColor</code></td><td>Background color</td><td>#FAFAFA</td></tr><tr><td><code>neutralColor</code></td><td>Color of the separating lines</td><td>#F0F0F0</td></tr><tr><td><code>warningColor</code></td><td>Warning color (non-critical hint)</td><td>#F7A334</td></tr><tr><td><code>criticalColor</code></td><td>Alert color (critical hint)</td><td>#E52027</td></tr></tbody></table>

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:

```xml
<?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>
```

{% hint style="info" %}
The flavor "`colorsTest`" of the demo application is an example of colors customization.
{% endhint %}

### 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:

```xml
<?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>

```

To override the secondary font, define your font family in the file `res/font/dksecondary.xml` in your app:

```xml
<?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>

```

{% hint style="info" %}
The flavor "`fontsTest`" of the demo application customizes the fonts to test and see where the different fonts are used.
{% endhint %}

### 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

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 [Github](https://github.com/DriveQuantPublic/drivekit-ui-android), in the src/main/res/values folder of each module.

### **Add language**

The translation file can be retrieved from [GitHub ](https://github.com/DriveQuantPublic/drivekit-ui-android)in the various DriveKit UI modules and integrated into the values-\<Locale> folder of the app.

### **Get analytics**

You can retrieve some data and build analytics for any DriveKit UI component. To enable the feature, call the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
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
    }
})
```

{% endtab %}

{% tab title="Java" %}

```java
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
   }
});

```

{% endtab %}
{% endtabs %}

`trackScreen()` method is called when a screen is displayed (i.e. trips list, trip detail, etc.).

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 [in this array](/common-ui/references), corresponding to the visited screen.

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.


# References

## Analytics tags

| 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            |


# 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.

{% hint style="info" %}
The Driver Data component uses standard and powerful libraries recommended by Apple and Google for persistence management. On Android, the [Room library](https://developer.android.com/topic/libraries/architecture/room) is implemented. On iOS, the [Core Data](https://developer.apple.com/documentation/coredata) persistence framework provided by Apple is used.
{% endhint %}

{% hint style="info" %}
We recommend you to test this component in the [DriveKit Demo App](/#the-drivekit-demo-app) before you integrate it in your application.
{% endhint %}


# iOS


# Get started

## Prerequisite

Before starting DriveKit Driver Data integration, make sure that you have [initialized DriveKit](/get-started-drivekit/ios).

{% hint style="danger" %}
If you use Driver Data without having initialized DriveKit, the SDK may not work properly in your application.
{% endhint %}

## Integration

### Get framework

To add the DriverData module to your app using **Swift Package Manager,** add `DriveKitDriverData` from repository: `https://github.com/DriveQuantPublic/drivekit-sdk-spm.git` as dependency.

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-the-sdk), an initialization phase is required to use the feature included in the Driver Data module. In the application's AppDelegate file, import `DriveKitDriverData:`

```swift
import DriveKitDriverDataModule
```

Then, to initialize Driver Data module in your app, you must call the initialization method in `didFinishLaunchingWithOptions` method of your AppDelegate file.

{% tabs %}
{% tab title="AppDelegate.swift" %}

```swift
import DriveKitCoreModule
import DriveKitTripAnalysisModule

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

{% endtab %}
{% endtabs %}

## Get driver trips

To get [Driver trips](/trip-analysis/ios/references#trip), you have to call the following method:

```swift
public func getTripsOrderByDateDesc(type: SynchronizationType = .defaultSync, completionHandler: @escaping (TripSyncStatus, [DKTrip]) -> ())
```

`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.

The second argument in the `completionHandler` is the list of [DKTrip](/trip-analysis/ios/references#trip) objects.&#x20;

{% hint style="info" %}
Trips are returned and sorted by end date in descending order.
{% endhint %}

{% hint style="warning" %}
If train trips have been recorded by Trip Analysis SDK, they won't be returned by this method.
{% endhint %}

Example:

```swift
DriveKitDriverData.shared.getTripsOrderByDateDesc(completionHandler: { status, trips in
    // Check status and use trips data
})
```

## Get specific trip

To get a specific [trip](/trip-analysis/ios/references#trip), you have to call the following method:

```swift
public func getTrip(itinId: String, completionHandler: @escaping (TripSyncStatus, DKTrip?) -> ())
```

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.

`TripSyncStatus` can have the same value as [above](/driver-data/ios/get-started#get-driver-trips) and the value `failedToSyncSafetyEvents` if the safety events synchronization failed.

The second argument in the `completionHandler` is the requested [Trip](/trip-analysis/ios/references#trip) object, if exists.&#x20;

Example:

```swift
DriveKitDriverData.shared.getTrip(itinId: itinId, completionHandler: { status, trip in
    // 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:

```swift
public func getRoute(itinId: String, completionHandler: @escaping (DKRoute?) -> ())
```

If `route` value in completionHandler is `nil` , the synchronization has failed.

Example:

```swift
DriveKitDriverData.shared.getRoute(itinId: itinId, completionHandler: { route in
    if let route = route {
        // Use route data
     } else {
        // Failed to synchronize route
     }
})
```

## Delete a trip

To delete a trip, you have to call the following method:

```swift
 public func deleteTrip(itinId: String, completionHandler: @escaping (Bool) -> ())
```

The `itinId` parameter is the unique identifier for a trip.

Example:

```swift
DriveKitDriverData.shared.deleteTrip(itinId: self.viewModel.itinId, completionHandler: { deleteSuccessful in
    if deleteSuccessful {
        // trip successfully deleted
    } else {
        // Failed to delete trip
    }
})
```

## Declare a trip made as passenger

When a trip is analyzed and the detected transportation mode is car, truck, or motorcycle, it is by default attributed to the driver. However, in some cases, the data may come from a passenger's smartphone.

\
In such cases, it is possible to indicate that the analyzed trip was recorded by an occupant of the vehicle who was not the driver.\
This section describes the method used to declare a trip as having been made as a passenger.

\
With this method, you can add a feature to your application that allows the user to declare that they were not the driver of the vehicle.

{% hint style="warning" %}
When a user declares that a trip was made as a passenger, it will **not** modify any scores related to the trip.
{% endhint %}

To declare a trip as a passenger with a comment, call the following code:

{% tabs %}
{% tab title="Swift" %}

```swift
let itinid = "myItineraryId"
let mode = DKDriverPassengerMode.passenger
let comment = "I was the passenger"
DriveKitDriverData.shared.updateDriverPassengerMode(itinId: itinid, mode: mode, comment: comment) { status in
	switch status {
	case .success:
    	// Success, the data have been updated in the local database
	case .userNotConnected:
    	// An error occurred, the user is not yet connected.
	case .invalidTransportationMode:
    	// Error, the trip was made with an alternative transport
	case .invalidItineraryId:
    	// Error, the provided itinerary identifier does not exist or has not been made by the user
	case .commentTooLong:
    	// Error, the comment is too long
	case .failedToUpdateMode:
    	// An error occurred, for example when the user has no network.
	}
}

```

{% endtab %}
{% endtabs %}

The method takes the following parameters:

| Field   | Type                  | Description                                         |
| ------- | --------------------- | --------------------------------------------------- |
| itinId  | String                | Unique trip identifier                              |
| mode    | DKDriverPassengerMode | Possible value: `driver` or `passenger`.            |
| comment | String                | The user can add a comment of up to 120 characters. |

The method returns a `UpdateDriverPassengerModeStatus` enum with the possible values:

<table><thead><tr><th width="316">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The passenger status has been successfully updated and local trip data is also updated.</td></tr><tr><td>userNotConnected</td><td>The user is not yet connected to DriveKit.</td></tr><tr><td>invalidItineraryId</td><td>The itinerary identifier does not exist.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>invalidTransportationMode</td><td>The trip was made with alternative transport.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>commentTooLong</td><td>The comment exceeds 120 characters.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>failedToUpdateMode</td><td>An error has occurred, for example if the user has no network.<br>Update is not taken into account and local trip data is not updated either.</td></tr></tbody></table>

## **Get driver synthesis**

To get driver synthesis data, you have to call the following method:

```swift
public func getSynthesis(type: SynchronizationType = .cache, completionHandler: @escaping (SynthesisSyncStatus, DKSynthesis?) -> ())
```

`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:

```swift
import DriveKitDriverDataModule

DriveKitDriverData.shared.getSynthesis(type: .defaultSync) { status, synthesis in
    // Check status and use synthesis
}
```

```swift
public func getDriverTimelines(periods: [DKPeriod], type: SynchronizationType = .defaultSync, completionHandler: @escaping (TimelineSyncStatus, [DKDriverTimeline]?) -> Void)
```

`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.

```swift
import DriveKitDriverDataModule

DriveKitDriverData.shared.getTimelines(periods: [.week, .month], type: .defaultSync) { (status, timelines) in
    // Check status and use timelines
}
```

## Get **driver timelines**

To get driver timelines, you have to call the following method:

```swift
public func getDriverTimelines(
    periods: [DKPeriod],
    ignoreItemsWithoutTripScored: Bool = false,
    type: SynchronizationType = .defaultSync,
    completionHandler: @escaping (TimelineSyncStatus, [DKDriverTimeline]?) -> Void
)
```

`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.

The second argument in the `completionHandler` is a list of [DKDriverTimeline](/driver-data/ios/references#dkdrivertimeline) object, one per period requested.&#x20;

Example:

```swift
import DriveKitDriverDataModule

DriveKitDriverData.shared.getDriverTimelines(periods: [.week, .month, .year], type: .defaultSync) { (status, timelines) in
    // Check status and use timelines
}
```

## Get driver profile

To get driver profile, you have to call the following method:

```swift
public func getDriverProfile(
   type: SynchronizationType = .defaultSync,
   completionHandler: @escaping (DKDriverProfileStatus, DKDriverProfile?) -> Void
)
```

`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.

The second argument in the completionHandler is the [`DKDriverProfile`](/driver-data/ios/references#dkdriverprofile) object requested.

```swift
import DriveKitDriverDataModule

DriveKitDriverData.shared.getDriverProfile(type: .defaultSync) { (status, driverProfile) in
    // Check status and use driverProfile
}
```


# References (iOS)

## DKDriverTimeline

`DKDriverTimeline` is an object that contains timeline data for the given period.

```java
public struct DKDriverTimeline: Codable {
    public let period: DKPeriod
    public let allContext: [DKAllContextItem]
    public let roadContexts: [DKRoadContext: [DKRoadContextItem]]
}
```

<table><thead><tr><th>Attribute</th><th width="255.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>period</td><td><a href="#dkperiod">DKPeriod</a></td><td>The kind of aggregation period for this timeline</td></tr><tr><td>allContext</td><td>[<a href="#dkallcontextitem">DKAllContextItem</a>]</td><td>The list of all global context sorted by date</td></tr><tr><td>roadContexts</td><td>[DKRoadContext: [<a href="#dkroadcontextitem">DKRoadContextItem</a>]]</td><td>The dictionary of all road context and their associated list of context data sorted by date</td></tr></tbody></table>

## DKAllContextItem

`DKAllContextItem` is an object that contains data for global context for the given period.

```swift
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?
}
```

<table><thead><tr><th width="223.33333333333331">Attribute</th><th width="212">Type</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td>Date</td><td>Start date of the given period</td></tr><tr><td>numberTripTotal</td><td>Int</td><td>Total number of trips made during the given period</td></tr><tr><td>numberTripScored</td><td>Int</td><td>Number of trips made that were long enough to have a score during the given period</td></tr><tr><td>distance</td><td>Double</td><td>Total distance travelled during the given period (in kilometers)</td></tr><tr><td>duration</td><td>Int</td><td>Total trip duration during the given period (in minutes)</td></tr><tr><td>safety</td><td><a href="#dksafety">DKSafety</a>?</td><td>Safety's score and sub scores for the given period (present only if safety score is configured and the period has some scored trips)</td></tr><tr><td>ecoDriving</td><td><a href="#dkecodriving">DKEcoDriving</a>?</td><td>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)</td></tr><tr><td>phoneDistraction</td><td><a href="#dkdistraction">DKDistraction</a>?</td><td>Distraction's score and sub scores for the given period (present only if distraction score is configured)</td></tr><tr><td>speeding</td><td><a href="#dkspeeding">DKSpeeding</a>?</td><td>Speeding's score and sub scores for the given period (present only if speeding score is configured)</td></tr><tr><td>drivingConditions</td><td><a href="#dkdrivingconditions">DKDrivingConditions</a>?</td><td>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)</td></tr></tbody></table>

## DKSafety

DKSafety is an object that contains data for safety's score and sub scores.

```swift
public struct DKSafety: Codable {
    public let score: Double
    public let acceleration: Int
    public let braking: Int
    public let adherence: Int
}
```

<table><thead><tr><th width="229">Attribute</th><th width="176.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td>Double</td><td>Global safety score for the given period (ranging from 3 to 10)</td></tr><tr><td>acceleration</td><td>Int</td><td>Number of harsh accelerations during the given period</td></tr><tr><td>braking</td><td>Int</td><td>Number of hard breakings during the given period</td></tr><tr><td>adherence</td><td>Int</td><td>Number of adherence limits during the given period</td></tr></tbody></table>

## DKEcoDriving

`DKEcoDriving` is an object that contains data for eco-driving's score and sub scores.

```swift
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
}
```

<table><thead><tr><th>Attribute</th><th width="178.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td>Double</td><td>Global eco-driving score for the given period (ranging from 6 to 10)</td></tr><tr><td>efficiencyAcceleration</td><td>Double</td><td>Sub score of acceleration efficiency for the given period (ranging from -5 to 5)</td></tr><tr><td>efficiencyBrake</td><td>Double</td><td>Sub score of braking efficiency for the given period (ranging from -5 to 5)</td></tr><tr><td>efficiencySpeedMaintain</td><td>Double</td><td>Sub score of speed maintain efficiency for the given period (ranging from 0 to 5)</td></tr><tr><td>fuelVolume</td><td>Double</td><td>Fuel consumption during the given period (in liters)</td></tr><tr><td>fuelSaving</td><td>Double</td><td>Achievable fuel savings during the given period (in liters)</td></tr><tr><td>co2Mass</td><td>Double</td><td>CO₂ mass consumed during the given period (in kilograms)</td></tr></tbody></table>

## DKDistraction

`DKDistraction` is an object that contains data for distraction's score and sub scores.

```swift
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
}
```

<table><thead><tr><th width="273.3333333333333">Attribute</th><th width="168">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td>Double</td><td>Global distraction score for the given period (ranging from 0 to 10)</td></tr><tr><td>unlock</td><td>Int</td><td>Number of screen unlocks during the given period</td></tr><tr><td>lock</td><td>Int</td><td>Number of screen locks during the given period</td></tr><tr><td>callForbiddenDuration</td><td>Int</td><td>Duration of forbidden calls during the given period (in seconds)</td></tr><tr><td>numberTripWithForbiddenCall</td><td>Int</td><td>Number of trips during which the driver made forbidden calls during the given period</td></tr><tr><td>callForbidden</td><td>Int</td><td>Number of forbidden calls during the given period</td></tr><tr><td>callAuthorizedDuration</td><td>Int</td><td>Duration of authorized calls during the given period (in seconds)</td></tr><tr><td>callAuthorized</td><td>Int</td><td>Number of authorized calls during the given period</td></tr></tbody></table>

## DKSpeeding

`DKSpeeding` is an object that contains data for speeding's score and sub scores.

```java
public struct DKSpeeding: Codable {
    public let score: Double
    public let speedingDuration: Int
    public let speedingDistance: Double
}
```

<table><thead><tr><th>Attribute</th><th width="173.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td>Double</td><td>Global speeding score for the given period (ranging from 0 to 10)</td></tr><tr><td>speedingDuration</td><td>Int</td><td>Overspeeding duration during the given period (in seconds)</td></tr><tr><td>speedingDistance</td><td>Double</td><td>Overspeeding distance travelled during the given period (in meters)</td></tr></tbody></table>

## DKDrivingConditions

`DKDrivingConditions` is an object that contains advanced driving information for the given period.

```swift
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
}
```

<table><thead><tr><th width="237.33333333333331">Attribute</th><th width="247">Type</th><th>Description</th></tr></thead><tbody><tr><td>tripCountByCategory</td><td><code>[</code><a href="#dkdrivingcategory"><code>DKDrivingCategory</code></a><code>: Int]</code></td><td>Total trips count by driving category</td></tr><tr><td>distanceByCategory</td><td><code>[</code><a href="#dkdrivingcategory"><code>DKDrivingCategory</code></a><code>: Double]</code></td><td>Total distance in km by driving category</td></tr><tr><td>tripCountByWeatherType</td><td><code>[</code><a href="/pages/bWMPXN276El7152nrY2X#dkweather"><code>DKWeather</code></a><code>: Int]</code></td><td>Total trips count by weather category</td></tr><tr><td>distanceByWeatherType</td><td><code>[</code><a href="/pages/bWMPXN276El7152nrY2X#dkweather"><code>DKWeather</code></a><code>: Double]</code></td><td>Total distance in km count by weather category</td></tr><tr><td>dayDistance</td><td><code>Double</code></td><td>Total distance traveled by the day in km </td></tr><tr><td>nightDistance</td><td><code>Double</code></td><td>Total distance traveled by night in km</td></tr><tr><td>weekdaysDistance</td><td><code>Double</code></td><td>Total distance traveled during weekdays in km</td></tr><tr><td>weekendDistance</td><td><code>Double</code></td><td>Total distance traveled during weekend in km</td></tr></tbody></table>

## DKDrivingCategory

```swift
public enum DKDrivingCategory: Int, Codable {
    case lessThan2Km = 0
    case from2To10Km = 1
    case from10To50Km = 2
    case from50To100Km = 3
    case moreThan100Km = 4
}
```

<table><thead><tr><th width="242">Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>lessThan2Km</code></td><td>Trip distance strictly below <code>2</code> km</td></tr><tr><td><code>from2To10Km</code></td><td>Trip distance in <code>[2, 10[</code> km</td></tr><tr><td><code>from10To50Km</code></td><td>Trip distance in <code>[10, 50[</code> km</td></tr><tr><td><code>from50To100Km</code></td><td>Trip distance in <code>[50, 100[</code> km</td></tr><tr><td><code>moreThan100Km</code></td><td>Trip distance is equals or above <code>100</code> km</td></tr></tbody></table>

## DKRoadContextItem

`DKRoadContextItem` is an object that contains data for the given road context and given period.

```swift
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?
}
```

<table><thead><tr><th width="223.33333333333331">Attribute</th><th width="197">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="#dkroadcontext">DKRoadContext</a></td><td>Road context for the given period</td></tr><tr><td>date</td><td>Date</td><td>Start date of the given period</td></tr><tr><td>numberTripTotal</td><td>Int</td><td>Total number of trips made during the given period and road context</td></tr><tr><td>numberTripScored</td><td>Int</td><td>Number of trips made that were long enough to have a score during the given period and road context</td></tr><tr><td>distance</td><td>Double</td><td>Total distance travelled during the given period and road context (in kilometers)</td></tr><tr><td>duration</td><td>Int</td><td>Total trip duration during the given period and road context (in minutes)</td></tr><tr><td>safety</td><td><a href="#dksafety">DKSafety</a>?</td><td>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)</td></tr><tr><td>ecoDriving</td><td><a href="#dkecodriving">DKEcoDriving</a>?</td><td>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)</td></tr></tbody></table>

***

## DKDriverProfile

`DKDriverProfile` is the object describing the driver profile.

| Attribute                    | Type                                                                          | Description                                              |
| ---------------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------- |
| distance                     | [DKDistanceProfile](#dkdistanceprofile)                                       | Distance class                                           |
| activity                     | [DKActivityProfile](#dkactivityprofile)                                       | Activity class                                           |
| regularity                   | [DKRegularityProfile](#dkregularityprofile)                                   | Regularity class                                         |
| mainRoadContext              | [DKRoadContex](#dkroadcontext)t                                               | Main road context                                        |
| mobility                     | [DKMobilityProfile](#dkmobilityprofile)                                       | Mobility class                                           |
| statistics                   | [DKDriverStatistics](#dkdriverstatistics)                                     | Statistics about the driver                              |
| weekRegularity               | [DKDriverRegularity](#dkdriverregularity)                                     | Information about driver’s week regularity               |
| monthRegularity              | [DKDriverRegularity](#dkdriverregularity)                                     | Information about driver’s month regularity              |
| distanceEstimation           | [DKDriverDistanceEstimation](#dkdriverdistanceestimation)                     | Distance estimation by week, month or year               |
| roadContextInfoByRoadContext | Map<[DKRoadContext](#dkroadcontext), [DKRoadContextInfo](#dkroadcontextinfo)> | Contains information about road contexts                 |
| commonTripByType             | Map<[DKCommonTripType](#dkcommontriptype), [DKCommonTrip](#dkcommontrip)>     | Provides information about common trips, by type of trip |
| mobilityAreaRadiusByType     | Map<[DKMobilityAreaType](#dkmobilityareatype), Int>                           | Provides radius of mobility area by type of mobility     |

```swift
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                  |

```swift
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 %             |

```swift
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 |

```swift
public enum DKRegularityProfile: String, Codable {
    case regular = "REGULAR"
    case intermittent = "INTERMITTENT"
}
```

## DKMobilityProfile

`DKMobilityProfile` indicates the mobility class of the driver.

<table><thead><tr><th width="225">Value</th><th>Description</th></tr></thead><tbody><tr><td>.narrow</td><td>90% of trips are within a radius of less than 10 km</td></tr><tr><td>.small</td><td>90% of trips are within a radius of less than 20 km</td></tr><tr><td>.medium</td><td>90% of trips are within a radius of less than 30 km</td></tr><tr><td>.large</td><td>90% of trips are within a radius of less than 50 km</td></tr><tr><td>.wide</td><td>90% of trips are within a radius of less  than 100 km</td></tr><tr><td>.vast</td><td>90% of trips are within a radius of 100 km or more</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="219">Attribute</th><th width="140.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>tripsNumber</td><td>Int</td><td>Total number of trips</td></tr><tr><td>totalDistance</td><td>Int</td><td>Total distance (in km)</td></tr><tr><td>totalDuration</td><td>Int</td><td>Total driving duration (in min)</td></tr><tr><td>weekNumber</td><td>Int</td><td>Number of weeks since user registration</td></tr><tr><td>activeWeekNumber</td><td>Int</td><td>Number of active weeks since user registration</td></tr><tr><td>monthNumber</td><td>Int</td><td>Number of months since user registration</td></tr><tr><td>activeMonthNumber</td><td>Int</td><td>Number of active months since user registration</td></tr><tr><td>peakTime</td><td>DKTime</td><td>Peak time trip starts</td></tr><tr><td>peakDay</td><td>DKDay</td><td>Weekday with most trips completed</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="295.3333333333333">Attribute</th><th width="118">Type</th><th>Description</th></tr></thead><tbody><tr><td>periodNumber</td><td>Int</td><td>Number of weeks or months used to calculate regularity</td></tr><tr><td>tripNumberMean</td><td>Int</td><td>Average number of trips per week or month</td></tr><tr><td>tripNumberStandardDeviation</td><td>Int</td><td>Standard deviation of the number of trips per week or month</td></tr><tr><td>distanceMean</td><td>Int</td><td>Average weekly or monthly distance (in km)</td></tr><tr><td>distanceStandardDeviation</td><td>Int</td><td>Standard deviation of the weekly or monthly distance (in km)</td></tr><tr><td>durationMean</td><td>Int</td><td>Average weekly or monthly driving duration (in min)</td></tr><tr><td>durationStandardDeviation</td><td>Int</td><td>Standard deviation of the weekly or monthly driving duration (in min)</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="184.33333333333331">Attribute</th><th width="340">Type</th><th>Description</th></tr></thead><tbody><tr><td>weekDistance</td><td>Int</td><td>Estimated weekly distance (in km)</td></tr><tr><td>monthDistance</td><td>Int</td><td>Estimated monthly distance (in km)</td></tr><tr><td>yearDistance</td><td>Int</td><td>Estimated annual distance (in km)</td></tr><tr><td>confidence</td><td><a href="#dkdriverdistanceestimationconfidence">DKDriverDistanceEstimationConfidence</a></td><td>Confidence level indicator, based on the available data</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="270">Value</th><th>Description</th></tr></thead><tbody><tr><td>.low</td><td>If less than 8 weeks since driver’s subscription</td></tr><tr><td>.medium</td><td>If between 9 and 16 weeks since driver’s subscription</td></tr><tr><td>.high</td><td>If more than 16 weeks since driver’s subscription</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="268.3333333333333">Attribute</th><th width="166">Type</th><th>Description</th></tr></thead><tbody><tr><td>roadContext</td><td><a href="#dkroadcontext">DKRoadContext</a></td><td>Road context</td></tr><tr><td>distancePercentage</td><td>Double</td><td>Percentage of total distance driven in this context</td></tr><tr><td>durationPercentage</td><td>Double</td><td>Percentage of total duration driven in this context</td></tr><tr><td>consumedEnergyPercentage</td><td>Double</td><td>Percentage of total energy driven in this context</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="272">Value</th><th>Description</th></tr></thead><tbody><tr><td>.mostFrequent</td><td>Most frequent trip</td></tr><tr><td>.unknown</td><td>Unknown type for the SDK (if a new type is added but the SDK is not up to date)</td></tr></tbody></table>

```swift
public enum DKCommonTripType: String, Codable {
    case mostFrequent = "MOST_FREQUENT"
    case unknown = "UNKNOWN"
}
```

## DKCommonTrip

`DKCommonTrip` is an object providing information about a trip.

<table><thead><tr><th width="209.33333333333331">Attribute</th><th width="227">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="#dkcommontriptype">DKCommonTripType</a></td><td>Type of trip</td></tr><tr><td>tripNumber</td><td>Int</td><td>Number of trips</td></tr><tr><td>distanceMean</td><td>Int</td><td>Average trip distance (in km)</td></tr><tr><td>durationMean</td><td>Int</td><td>Average trip duration (in min)</td></tr><tr><td>roadContext</td><td><a href="#dkroadcontext">DKRoadContext</a></td><td>Road context type</td></tr></tbody></table>

```swift
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.

<table><thead><tr><th width="222">Value</th><th>Description</th></tr></thead><tbody><tr><td>.percentile50Th</td><td>The radius including 50% of all the user’s trips</td></tr><tr><td>.percentile90Th</td><td>The radius including 90% of all the user’s trips</td></tr></tbody></table>

```swift
public enum DKMobilityAreaType: String, Codable {
    case percentile50Th = "PERCENTILE_50TH"
    case percentile90Th = "PERCENTILE_90TH"
}
```


# Android


# Get started

## Prerequisite

Before starting DriveKit Driver Data integration, make sure that you have [initialized DriveKit](/get-started-drivekit/android).

{% hint style="danger" %}
If you use DriveKit Driver Data without having initialized DriveKit, an exception will be generated and the SDK will not work in your application.
{% endhint %}

## 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:

```gradle
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-driver-data:$drivekit_version'
}
```

{% hint style="info" %}
Replace `$drivekit_version` with the DriveKit version you are using in your app
{% endhint %}

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), 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.

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun initialize()
```

{% endtab %}
{% endtabs %}

## Get driver trips

To get [Driver trips](/trip-analysis/android/references#trip), you have to call the following method:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getTripsOrderByDateDesc(listener: TripsQueryListener, type: SynchronizationType = SynchronizationType.DEFAULT)
```

{% endtab %}
{% endtabs %}

`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.&#x20;

```kotlin
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

The second argument of the `onResponse` method is a list of [Trip](/trip-analysis/android/references#trip) objects.

{% hint style="info" %}
Trips are returned and sorted by end date in descending order.
{% endhint %}

Example:

```kotlin
DriveKitDriverData.getTripsOrderByDateDesc(object: TripsQueryListener {
                override fun onResponse(status: TripsSyncStatus, trips: List<Trip>) {
                    // Check status and trips data
                }
            }, SynchronizationType.DEFAULT)
```

## Get specific trip

To get a specific [trip](/trip-analysis/android/references#trip), you have to call the following method:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getTrip(itinId: String, listener: TripQueryListener)
```

{% endtab %}
{% endtabs %}

The `itinId` parameter is the unique identifier for a trip.

An implementation of `TripQueryListener` must be provided in order to retrieve the trip.&#x20;

```kotlin
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.

TripSyncStatus can have the same value as [above](/driver-data/ios/get-started#get-driver-trips) and the value `FAILED_TO_SYNC_SAFETY_EVENTS` if the safety events synchronization failed.

The second argument of the `onResponse` method is the requested [Trip](/trip-analysis/android/references#trip) object, if exists.

Example:

```kotlin
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:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getRoute(itinId: String, listener: RouteQueryListener)
```

{% endtab %}
{% endtabs %}

An implementation of `RouteQueryListener` must be provided in order to retrieve the trip.&#x20;

```kotlin
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:

```kotlin
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:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun deleteTrip(itinId: String, listener: TripDeleteQueryListener)
```

{% endtab %}
{% endtabs %}

The `itinId` parameter is the unique identifier for a trip.

Example:

```kotlin
DriveKitDriverData.deleteTrip(itinId, object: TripDeleteQueryListener {
    override fun onResponse(status: Boolean) {
        if (status) {
            //Trip succesfully deleted
        } else {
            // Failed to delete trip
        }
    }
})
```

## Declare a trip made as passenger

When a trip is analyzed and the detected transportation mode is car, truck, or motorcycle, it is by default attributed to the driver. However, in some cases, the data may come from a passenger's smartphone.

\
In such cases, it is possible to indicate that the analyzed trip was recorded by an occupant of the vehicle who was not the driver.\
This section describes the method used to declare a trip as having been made as a passenger.

\
With this method, you can add a feature to your application that allows the user to declare that they were not the driver of the vehicle.

{% hint style="warning" %}
When a user declares that a trip was made as a passenger, it will **not** modify any scores related to the trip.
{% endhint %}

To declare a trip as a passenger with a comment, call the following code:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitDriverData.updateDriverPassengerMode(
    itinId = "myItineraryId",
    mode = DriverPassengerMode.PASSENGER,
    comment = "I was the passenger"
) { status: UpdateDriverPassengerModeStatus ->
    when (status) {
        UpdateDriverPassengerModeStatus.SUCCESS -> {
            // Success, the data have been updated in the local database
        }
        UpdateDriverPassengerModeStatus.INVALID_ITINERARY_ID -> {
            // Error, the provided itinerary identifier does not exist or has not been made by the user
        }
        UpdateDriverPassengerModeStatus.INVALID_TRANSPORTATION_MODE -> {
            // Error, the trip was made with an alternative transport
        }
        UpdateDriverPassengerModeStatus.COMMENT_TOO_LONG -> {
            // Error, the comment is too long
        }
        UpdateDriverPassengerModeStatus.FAILED_TO_UPDATE_MODE -> {
            // An error occurred, for example when the user has no network.
        }
        UpdateDriverPassengerModeStatus.USER_NOT_CONNECTED -> {
            // An error occurred, the user is not yet connected.
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
final String itinId = "myItineraryId";
final DriverPassengerMode mode = DriverPassengerMode.PASSENGER;
final String comment = "I was the passenger";
DriveKitDriverData.updateDriverPassengerMode(itinId, mode, comment, status -> {
    switch (status) {
        case SUCCESS -> {
            // Success, the data have been updated in the local database
        }
        case INVALID_ITINERARY_ID -> {
            // Error, the provided itinerary identifier does not exist or has not been made by the user
        }
        case INVALID_TRANSPORTATION_MODE -> {
            // Error, the trip was made with an alternative transport
        }
        case COMMENT_TOO_LONG -> {
            // Error, the comment is too long
        }
        case FAILED_TO_UPDATE_MODE -> {
            // An error occurred, for example when the user has no network.
        }
        case USER_NOT_CONNECTED -> {
            // An error occurred, the user is not yet connected.
        }
    }
    return null;
});
```

{% endtab %}
{% endtabs %}

The method takes the following parameters:

| Field   | Type                | Description                                         |
| ------- | ------------------- | --------------------------------------------------- |
| itinId  | String              | Unique trip identifier                              |
| mode    | DriverPassengerMode | Possible value: `DRIVER` or `PASSENGER`.            |
| comment | String              | The user can add a comment of up to 120 characters. |

The method returns a `UpdateDriverPassengerModeStatus` enum with the possible values:

<table><thead><tr><th width="316">Value</th><th>Description</th></tr></thead><tbody><tr><td>SUCCESS</td><td>The passenger status has been successfully updated and local trip data is also updated.</td></tr><tr><td>USER_NOT_CONNECTED</td><td>The user is not yet connected to DriveKit.</td></tr><tr><td>INVALID_ITINERARY_ID</td><td>The itinerary identifier does not exist.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>INVALID_TRANSPORTATION_MODE</td><td>The trip was made with alternative transport.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>COMMENT_TOO_LONG</td><td>The comment exceeds 120 characters.<br>Update is not taken into account and local trip data is not updated either.</td></tr><tr><td>FAILED_TO_UPDATE_MODE</td><td>An error has occurred, for example if the user has no network.<br>Update is not taken into account and local trip data is not updated either.</td></tr></tbody></table>

## **Get driver synthesis**

To get driver synthesis data, you have to call the following method:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getSynthesis(
   listener: SynthesisQueryListener,
   synchronizationType: SynchronizationType)
```

{% endtab %}
{% endtabs %}

An implementation of SynthesisQueryListener must be provided in order to retrieve synthesis data.

```kotlin
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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitDriverData.getSynthesis(object : SynthesisQueryListener {
    override fun onResponse(
        synthesisStatus: SynthesisStatus,
        synthesis: Synthesis?
    ) {
        // Check synthesisStatus and use synthesis data
    }
})
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitDriverData.INSTANCE.getSynthesis(new SynthesisQueryListener() {
            @Override
            public void onResponse(@NotNull SynthesisStatus synthesisStatus,                    @Nullable Synthesis synthesis) {
                  // Check synthesisStatus and use synthesis data
            }
        }, SynchronizationType.DEFAULT);
```

{% endtab %}
{% endtabs %}

## Get **driver timelines**

To get driver timelines, you have to call the following method:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getDriverTimelines(
        periods: List<DKPeriod>,
        synchronizationType: SynchronizationType = SynchronizationType.DEFAULT,
        ignoreItemsWithoutTripScored: Boolean = false,
        callback: (timelineSyncStatus: TimelineSyncStatus, timelines: List<DKDriverTimeline>) -> Unit
)
```

{% endtab %}
{% endtabs %}

| Parameter name               | Type                | Description                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| periods                      | `DKTimelinePeriod`  | <p>Get timeline data in a specific period of time.<br>Possible values are : <code>WEEK</code>, <code>MONTH</code>, <code>YEAR</code></p>                                                                                                                                                                                                                                                                |
| synchronizationType          | SynchronizationType | <p>Define the source of the timelines data you want to retrieve.<br><br>Possible values are:<br><br><code>CACHE</code>: No sync will be performed and the data retrieved during the last sync will be returned via the <code>callback</code>.</p><p><br><code>DEFAULT</code>: the SDK will try to synchronize timelines with DriveQuant backend and then return them via the <code>callback</code>.</p> |
| ignoreItemsWithoutTripScored | Boolean             | If set to `true`, the returned timeline data will not contain items ([DKAllContextItem](/driver-data/android/references#dkallcontextitem) and [DKRoadContextItem](/driver-data/android/references#dkroadcontextitem)) where there are only unscored trips.                                                                                                                                              |

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.

The second argument in the `callback` is a list of [DKDriverTimeline](https://docs.drivequant.com/driver-data/android/references#dkdrivertimeline) object, one per requested period.

## Get driver profile

To get driver profile, you have to call the following method:

{% tabs %}
{% tab title="DriveKitDriverData" %}

```kotlin
fun getDriverProfile(
    synchronizationType: SynchronizationType = SynchronizationType.DEFAULT,
    callback: (status: DKDriverProfileStatus, driverProfile: DKDriverProfile?) -> Unit
)
```

{% endtab %}
{% endtabs %}

`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.

The second argument in the callback is the [`DKDriverProfile`](/driver-data/android/references#dkdriverprofile) object requested.

Example:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import com.drivequant.drivekit.driverdata.DriveKitDriverData

DriveKitDriverData.getDriverProfile(type: DKDriverProfileStatus.DEFAULT) { status, driverProfile ->
    // Check status and use driverProfile
}
```

{% endtab %}

{% tab title="Java" %}

```java
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;
});
```

{% endtab %}
{% endtabs %}


# References (Android)

## DKDriverTimeline

`DKDriverTimeline` is an object that contains timeline data for the given period.

```kotlin
data class DKDriverTimeline(
    val period: DKPeriod,
    val allContext: List<DKAllContextItem>,
    val roadContexts: Map<RoadContext, List<DKRoadContextItem>>
) : Serializable
```

<table data-header-hidden><thead><tr><th>Attribute</th><th width="255.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>Attribute</td><td>Type</td><td>Description</td></tr><tr><td>period</td><td>DKPeriod</td><td>The kind of aggregation period for this timeline</td></tr><tr><td>allContext</td><td>List&#x3C;<a href="#dkallcontextitem">DKAllContextItem</a>></td><td>The list of all global context sorted by date</td></tr><tr><td>roadContexts</td><td>Map&#x3C;<a href="#roadcontext">RoadContext</a>, List&#x3C;<a href="#dkroadcontextitem">DKRoadContextItem</a>>></td><td>The map of all road context and their associated list of context data sorted by date</td></tr></tbody></table>

## DKAllContextItem

`DKAllContextItem` is an object that contains data for global context for the given period.

```kotlin
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
```

<table data-header-hidden><thead><tr><th width="223.33333333333331">Attribute</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>Attribute</td><td>Type</td><td>Description</td></tr><tr><td>date</td><td>Date</td><td>Start date of the given period</td></tr><tr><td>numberTripTotal</td><td>Int</td><td>Total number of trips made during the given period</td></tr><tr><td>numberTripScored</td><td>Int</td><td>Number of trips made that were long enough to have a score during the given period</td></tr><tr><td>distance</td><td>Double</td><td>Total distance travelled during the given period (in kilometers)</td></tr><tr><td>duration</td><td>Int</td><td>Total trip duration during the given period (in minutes)</td></tr><tr><td>safety</td><td><a href="#dksafety">DKSafety</a>?</td><td>Safety's score and sub scores for the given period (present only if safety score is configured and the period has some scored trips)</td></tr><tr><td>ecoDriving</td><td><a href="#dkecodriving">DKEcoDriving</a>?</td><td>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)</td></tr><tr><td>phoneDistraction</td><td><a href="#dkdistraction">DKDistraction</a>?</td><td>Distraction's score and sub scores for the given period (present only if distraction score is configured)</td></tr><tr><td>speeding</td><td><a href="#dkspeeding">DKSpeeding</a>?</td><td>Speeding's score and sub scores for the given period (present only if speeding score is configured)</td></tr><tr><td>drivingConditions</td><td><a href="#dkdrivingconditions">DKDrivingConditions</a>?</td><td>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)</td></tr></tbody></table>

## DKSafety

`DKSafety` is an object that contains data for safety's score and sub scores.

```kotlin
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.

```kotlin
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.

```kotlin
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.

```kotlin
data class DKSpeeding(
    val score: Double,
    val speedingDuration: Int,
    val speedingDistance: Double,
) : Serializable
```

<table><thead><tr><th>Attribute</th><th width="255.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>score</td><td>Double</td><td>Global speeding score for the given period (ranging from 0 to 10)</td></tr><tr><td>speedingDuration</td><td>Int</td><td>Overspeeding duration during the given period (in seconds)</td></tr><tr><td>speedingDistance</td><td>Double</td><td>Overspeeding distance travelled during the given period (in meters)</td></tr></tbody></table>

## DKDrivingConditions

`DKDrivingConditions` is an object that contains advanced driving information for the given period.

```kotlin
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
```

<table><thead><tr><th width="245">Attribute</th><th width="270.3333333333333">Type</th><th>Description</th></tr></thead><tbody><tr><td>tripCountByCategory</td><td><code>Map&#x3C;</code><a href="#dkdrivingcategory"><code>DKDrivingCategory</code></a><code>, Int></code></td><td>Total trips count by driving category</td></tr><tr><td>distanceByCategory</td><td><code>Map&#x3C;</code><a href="#dkdrivingcategory"><code>DKDrivingCategory</code></a><code>, Double></code></td><td>Total distance in km by driving category</td></tr><tr><td>tripCountByWeatherType</td><td><code>Map&#x3C;</code><a href="/pages/6xYxZUY27ZMJpgnRq7AA#dkweather"><code>DKWeather</code></a><code>, Int></code></td><td>Total trips count by weather category</td></tr><tr><td>distanceByWeatherType</td><td><code>Map&#x3C;</code><a href="/pages/6xYxZUY27ZMJpgnRq7AA#dkweather"><code>DKWeather</code></a><code>, Double></code></td><td>Total distance in km count by weather category</td></tr><tr><td>dayDistance</td><td><code>Double</code></td><td>Total distance traveled by the day in km </td></tr><tr><td>nightDistance</td><td><code>Double</code></td><td>Total distance traveled by night in km</td></tr><tr><td>weekdaysDistance</td><td><code>Double</code></td><td>Total distance traveled during weekdays in km</td></tr><tr><td>weekendDistance</td><td><code>Double</code></td><td>Total distance traveled during weekend in km</td></tr></tbody></table>

## DKDrivingCategory

```kotlin
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);
}
```

<table><thead><tr><th width="242">Attribute</th><th>Description</th></tr></thead><tbody><tr><td><code>LESS_THAN_2_KM</code></td><td>Trip distance strictly below <code>2</code> km</td></tr><tr><td><code>FROM_2_TO_10_KM</code></td><td>Trip distance in <code>[2, 10[</code> km</td></tr><tr><td><code>FROM_10_TO_50_KM</code></td><td>Trip distance in <code>[10, 50[</code> km</td></tr><tr><td><code>FROM_50_TO_100_KM</code></td><td>Trip distance in <code>[50, 100[</code> km</td></tr><tr><td><code>MORE_THAN_100_KM</code></td><td>Trip distance is equals or above <code>100</code> km</td></tr></tbody></table>

## DKRoadContextItem

`DKRoadContextItem` is an object that contains data for the given road context and given period.

```kotlin
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
```

<table><thead><tr><th width="223.33333333333331">Attribute</th><th width="192">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="#roadcontext">RoadContext</a></td><td>Road context for the given period</td></tr><tr><td>date</td><td>Date</td><td>Start date of the given period</td></tr><tr><td>numberTripTotal</td><td>Int</td><td>Total number of trips made during the given period and road context</td></tr><tr><td>numberTripScored</td><td>Int</td><td>Number of trips made that were long enough to have a score during the given period and road context</td></tr><tr><td>distance</td><td>Double</td><td>Total distance travelled during the given period and road context (in kilometers)</td></tr><tr><td>duration</td><td>Int</td><td>Total trip duration during the given period and road context (in minutes)</td></tr><tr><td>safety</td><td><a href="#dksafety">DKSafety</a>?</td><td>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)</td></tr><tr><td>ecoDriving</td><td><a href="#dkecodriving">DKEcoDriving</a>?</td><td>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)</td></tr></tbody></table>

***

## DKDriverProfile

`DKDriverProfile` is the object describing the driver profile.

| Attribute                    | Type                                                                      | Description                                              |
| ---------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------- |
| distance                     | [DKDistanceProfile](#dkdistanceprofile)                                   | Distance class                                           |
| activity                     | [DKActivityProfile](#dkactivityprofile)                                   | Activity class                                           |
| regularity                   | [DKRegularityProfile](#dkregularityprofile)                               | Regularity class                                         |
| mainRoadContext              | [RoadContext](#roadcontext)                                               | Main road context                                        |
| mobility                     | [DKMobilityProfile](#dkmobilityprofile)                                   | Mobility class                                           |
| statistics                   | [DKDriverStatistics](#dkdriverstatistics)                                 | Statistics about the driver                              |
| weekRegularity               | [DKDriverRegularity](#dkdriverregularity)                                 | Information about driver’s week regularity               |
| monthRegularity              | [DKDriverRegularity](#dkdriverregularity)                                 | Information about driver’s month regularity              |
| distanceEstimation           | [DKDriverDistanceEstimation](#dkdriverdistanceestimation)                 | Distance estimation by week, month or year               |
| roadContextInfoByRoadContext | Map<[RoadContext](#roadcontext), [DKRoadContextInfo](#dkroadcontextinfo)> | Contains information about road contexts                 |
| commonTripByType             | Map<[DKCommonTripType](#dkcommontriptype), [DKCommonTrip](#dkcommontrip)> | Provides information about common trips, by type of trip |
| mobilityAreaRadiusByType     | Map<[DKMobilityAreaType](#dkmobilityareatype), Int>                       | Provides radius of mobility area by type of mobility     |

```java
@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                  |

```java
@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 %             |

```java
@Keep
enum class DKActivityProfile {
    LOW,
    MEDIUM,
    HIGH
}
```

## DKRegularityProfile

`DKRegularityProfile` indicates the regularity class of the driver.

| Value        | Description         |
| ------------ | ------------------- |
| REGULAR      | Regular driver      |
| INTERMITTENT | Intermittent driver |

```java
@Keep
enum class DKRegularityProfile {
    REGULAR,
    INTERMITTENT
}
```

## DKMobilityProfile

`DKMobilityProfile` indicates the mobility class of the driver.

<table><thead><tr><th width="225">Value</th><th>Description</th></tr></thead><tbody><tr><td>NARROW</td><td>90% of trips are within a radius of less than 10 km</td></tr><tr><td>SMALL</td><td>90% of trips are within a radius of less than 20 km</td></tr><tr><td>MEDIUM</td><td>90% of trips are within a radius of less than 30 km</td></tr><tr><td>LARGE</td><td>90% of trips are within a radius of less than 50 km</td></tr><tr><td>WIDE</td><td>90% of trips are within a radius of less  than 100 km</td></tr><tr><td>VAST</td><td>90% of trips are within a radius of 100 km or more</td></tr></tbody></table>

```java
@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               |

```java
@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.

<table><thead><tr><th width="280.3333333333333">Attribute</th><th width="101">Type</th><th>Description</th></tr></thead><tbody><tr><td>periodNumber</td><td>Int</td><td>Number of weeks or months used to calculate regularity</td></tr><tr><td>tripNumberMean</td><td>Int</td><td>Average number of trips per week or month</td></tr><tr><td>tripNumberStandardDeviation</td><td>Int</td><td>Standard deviation of the number of trips per week or month</td></tr><tr><td>distanceMean</td><td>Int</td><td>Average weekly or monthly distance (in km)</td></tr><tr><td>distanceStandardDeviation</td><td>Int</td><td>Standard deviation of the weekly or monthly distance (in km)</td></tr><tr><td>durationMean</td><td>Int</td><td>Average weekly or monthly driving duration (in min)</td></tr><tr><td>durationStandardDeviation</td><td>Int</td><td>Standard deviation of the weekly or monthly driving duration (in min)</td></tr></tbody></table>

```java
@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.

<table><thead><tr><th width="202.33333333333331">Attribute</th><th width="253">Type</th><th>Description</th></tr></thead><tbody><tr><td>weekDistance</td><td>Int</td><td>Estimated weekly distance (in km)</td></tr><tr><td>monthDistance</td><td>Int</td><td>Estimated monthly distance (in km)</td></tr><tr><td>yearDistance</td><td>Int</td><td>Estimated annual distance (in km)</td></tr><tr><td>confidence</td><td><a href="#dkdriverdistanceestimationconfidence">DKDriverDistanceEstimationConfidence</a></td><td>Confidence level indicator, based on the available data</td></tr></tbody></table>

```java
@Keep
data class DKDriverDistanceEstimation(
    val weekDistance: Int,
    val monthDistance: Int,
    val yearDistance: Int,
    val confidence: DKDriverDistanceEstimationConfidence
)
```

## DKDriverDistanceEstimationConfidence

`DKDriverDistanceEstimationConfidence` indicates the distance estimation confidence class.

<table><thead><tr><th width="170">Value</th><th>Description</th></tr></thead><tbody><tr><td>LOW</td><td>If less than 8 weeks since driver’s subscription</td></tr><tr><td>MEDIUM</td><td>If between 9 and 16 weeks since driver’s subscription</td></tr><tr><td>HIGH</td><td>If more than 16 weeks since driver’s subscription</td></tr></tbody></table>

```java
@Keep
enum class DKDriverDistanceEstimationConfidence {
    LOW,
    MEDIUM,
    HIGH
}
```

## DKRoadContextInfo

`DKRoadContextInfo` is an object providing information about road context for the driver.

<table><thead><tr><th width="270.3333333333333">Attribute</th><th width="174">Type</th><th>Description</th></tr></thead><tbody><tr><td>roadContext</td><td><a href="#roadcontext">RoadContext</a></td><td>Road context</td></tr><tr><td>distancePercentage</td><td>Double</td><td>Percentage of total distance driven in this context</td></tr><tr><td>durationPercentage</td><td>Double</td><td>Percentage of total duration driven in this context</td></tr><tr><td>consumedEnergyPercentage</td><td>Double</td><td>Percentage of total energy driven in this context</td></tr></tbody></table>

```java
@Keep
data class DKRoadContextInfo(
    val roadContext: RoadContext,
    val distancePercentage: Double,
    val durationPercentage: Double,
    val consumedEnergyPercentage: Double
)
```

## DKCommonTripType

`DKCommonTripType` indicates the type of trip.

<table><thead><tr><th width="231">Value</th><th>Description</th></tr></thead><tbody><tr><td>MOST_FREQUENT</td><td>Most frequent trip</td></tr><tr><td>UNKNOWN</td><td>Unknown type for the SDK (if a new type is added but the SDK is not up to date)</td></tr></tbody></table>

```java
@Keep
enum class DKCommonTripType {
    MOST_FREQUENT,
    UNKNOWN
}
```

## DKCommonTrip

`DKCommonTrip` is an object providing information about a trip.

<table><thead><tr><th width="207">Attribute</th><th width="197.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="#dkcommontriptype">DKCommonTripType</a></td><td>Type of trip</td></tr><tr><td>tripNumber</td><td>Int</td><td>Number of trips</td></tr><tr><td>distanceMean</td><td>Int</td><td>Average trip distance (in km)</td></tr><tr><td>durationMean</td><td>Int</td><td>Average trip duration (in min)</td></tr><tr><td>roadContext</td><td><a href="#roadcontext">RoadContext</a></td><td>Road context type</td></tr></tbody></table>

```java
@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.

<table><thead><tr><th width="264">Value</th><th>Description</th></tr></thead><tbody><tr><td>PERCENTILE_50TH</td><td>The radius including 50% of all the user’s trips</td></tr><tr><td>PERCENTILE_90TH</td><td>The radius including 90% of all the user’s trips</td></tr></tbody></table>

```java
@Keep
enum class DKMobilityAreaType {
    PERCENTILE_50TH,
    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.

<figure><img src="/files/m9n7dxCIwNb0IxC6QTwk" alt=""><figcaption><p>Trip list and trip detail screens provided into the Driver Data SDK graphics library</p></figcaption></figure>

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.

<figure><img src="/files/7QbfAF20XtUym5XdHN3w" alt=""><figcaption><p>Trip details screens</p></figcaption></figure>

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.

<figure><img src="/files/4XawsnjE5Z2ximb2I6Xv" alt=""><figcaption><p>Trips widgets</p></figcaption></figure>

## 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.

<figure><img src="/files/hu9bcQbom5BodD9Mfmg7" alt=""><figcaption><p>My synthesis screen</p></figcaption></figure>

You can find more details on the [iOS](/driver-data/user-interface/ios/my-synthesis) and [Android](/driver-data/user-interface/android/my-synthesis) documentation.

## 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,&#x20;
* his regularity,&#x20;
* 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.

<figure><img src="/files/VnE6ZRm61E5nOTml0rL9" alt=""><figcaption><p>My Driver Profile screens</p></figcaption></figure>

<br>


# iOS


# Get started

## Prerequisite

Before starting DriveKit Driver Data UI integration, make sure that you have [initialized DriverData](/driver-data/ios/get-started) and [Common UI](/common-ui/ios/get-started) components, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-the-sdk).

## Integration

### Get the framework

To add the DriverData UI module to your app:

* **Swift Package Manager:** Add `DriveKitDriverDataUI` from repository: `https://github.com/DriveQuantPublic/drivekit-ui-ios.git` as dependency.
* **Cocoapods** (deprecation scheduled for the end of 2025)**:** add the following pod to your Podfile:

{% tabs %}
{% tab title="Podfile" %}

```ruby
target 'my-target' do
  pod 'DriveKitDriverDataUI'
end
```

{% endtab %}
{% endtabs %}

Then, run `pod install`.

{% hint style="info" %}
On this [Github repository](https://github.com/DriveQuantPublic/drivekit-ui-ios), you also have a demo app and source code of Driver Data UI that you can use as an example.
{% endhint %}

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-the-sdk), the Driver Data UI module must also be manually initialized. In the application's AppDelegate file, import `DriveKitDriverDataUI`:

```swift
import DriveKitDriverDataUI
```

Then, to initialize Driver Data UI SDK in your app, you must call the initialization method in `didFinishLaunchingWithOptions` method of your AppDelegate:

{% tabs %}
{% tab title="AppDelegate.swift" %}

```swift
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()
    ...    
}
```

{% endtab %}
{% endtabs %}

### Override colors and texts

To override colors and texts in Driver Data UI SDK, see [Common UI configuration](/common-ui/ios/get-started).&#x20;

### 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:&#x20;

* `.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.

{% hint style="warning" %}
The value .`speeding` can be set only if this configuration is enabled for your API key.
{% endhint %}

The main theme is configured in the SDK `initialize` method by setting the parameter `tripData`.

```swift
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`.

{% hint style="warning" %}
The value .`speeding` can be set only if this configuration is activated on your team.
{% endhint %}

The main theme is configured in the SDK `initialize` method by setting the parameter `mapItems`.

```swift
DriveKitDriverDataUI.shared.initialize(mapItems: [.safety, .ecoDriving, .distraction, .speeding, .interactiveMap, .synthesis])
```

The default value is:

&#x20;`[.safety, .ecoDriving, .distraction, .speeding, .interactiveMap, .synthesis]`

{% hint style="info" %}
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.
{% endhint %}

<figure><img src="/files/NYSIdcyf3X3Cs1asuAAf" alt=""><figcaption><p>Trip map items</p></figcaption></figure>

## 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.

```swift
let tripListVC = TripListVC()
self.navigationController?.pushViewController(tripListVC, animated: true)
```


# 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.&#x20;

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`:

```swift
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`:

```swift
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`:

```swift
DriveKitDriverDataUI.shared.enableAdviceFeedback(enable: false)
```

<figure><img src="/files/eZbGMmI0KtVhCk2Bedj6" alt=""><figcaption><p>Eco-driving advice</p></figcaption></figure>

## 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.

```swift
DriveKitDriverDataUI.shared.enableAlternativeTrips(true)
```

<figure><img src="/files/hLUzGqlrGZwFRsPJg3jN" alt=""><figcaption><p>Alternative transportation mode list</p></figcaption></figure>


# 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.

<figure><img src="/files/I3D9OxkC7FyJmhv41TDX" alt=""><figcaption></figcaption></figure>

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:

```swift
DriveKitDriverDataUI.shared.getLastTripsSynthesisCardsView([.safety, .ecodriving, .distraction, .speeding])
```

{% hint style="info" %}
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.
{% endhint %}

{% hint style="warning" %}
The value .speeding can be set only if this configuration is enabled for your API key.
{% endhint %}

## Last trip widget

The Driver Data component includes a widget to display a short chronological list of the driver's last trips.

<figure><img src="/files/q2rsZQqUoLftkwJIZkWp" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/mBh467b11TRjgQ0VTS6p" alt=""><figcaption></figcaption></figure>

​​To include the last trip widget into your app, call the following method:

```swift
DriveKitDriverDataUI.shared.getLastTripsView(parentViewController: <a_view_controller>)
```

And embed the returned view into your layout.


# 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 ;&#x20;
* 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.

<figure><img src="/files/hu9bcQbom5BodD9Mfmg7" alt=""><figcaption><p>My synthesis screen</p></figcaption></figure>

​​To include the “My Synthesis” screen into your app, call the following method:

```swift
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:

```swift
DriveKitUI.shared.scores = [.safety, .ecoDriving, .distraction, .speeding]
```

Default and accepted values are:

```
[.safety, .ecoDriving, .distraction, .speeding]
```

{% hint style="warning" %}
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.
{% endhint %}


# 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.

<figure><img src="/files/VnE6ZRm61E5nOTml0rL9" alt=""><figcaption><p>My Driver Profile 2 screens</p></figcaption></figure>

## 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:&#x20;

* 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,&#x20;
* the regularity based on the relative standard deviations of the weekly distance and trip number,
* the main driving context.

<figure><img src="/files/XXbp5vQh43W2al9SxOEX" alt=""><figcaption><p>Driver's profile cards</p></figcaption></figure>

### 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.

<figure><img src="/files/GjJ7Uj5hqElUuZh81EK7" alt=""><figcaption><p>Distance estimation cards</p></figcaption></figure>

### Driver’s usual trip

The purpose of this section is to highlight the driver's most common trip in terms of duration and distance.

<figure><img src="/files/USug2ZEkoVIQ2KiRixUc" alt=""><figcaption><p>Driver's usual trip</p></figcaption></figure>

{% hint style="info" %}
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.
{% endhint %}

​​To include the “Driver Profile” screen into your app, call the following method:

```swift
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.

<figure><img src="/files/xCNKJdwzSVXqFlHfZqdA" alt=""><figcaption><p>Driving conditions screen</p></figcaption></figure>

If you want to include the “Driving Conditions” screen into your app as a standalone screen, call the following method:

```kotlin
DriveKitDriverDataUI.shared.getDrivingConditionsViewController()
```

And present the returned view controller using your app’s navigation API.


# Android


# Get Started

## Pre-requisite

Before starting DriveKit Driver Data UI integration, make sure that you have [initialized DriverData](/driver-data/android/get-started) and [Common UI](/common-ui/android/get-started) components, especially if you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk).&#x20;

## Integration

To add Driver Data UI module to your app, add the following line to your dependencies in your application build.gradle file:

{% tabs %}
{% tab title="build.gradle" %}

```gradle
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-driver-data-ui:$drivekitui_version'
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Replace `$drivekitui_version` with the DriveKit version you are using in your app
{% endhint %}

{% hint style="info" %}
On a [Github repository](https://github.com/DriveQuantPublic/drivekit-ui-android), you have a demo app and source code of Driver Data UI that you can use as an example.
{% endhint %}

## 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.

According to the [official documentation](https://developers.google.com/maps/documentation/android-sdk/get-api-key), please check that you already have:

* a billing account
* Maps SDK for Android enabled

If you already have a Google API Key that can be used for Maps SDK, directly go to the [Adding the API Key to your app](https://developers.google.com/maps/documentation/android-sdk/get-api-key#add_key) section<br>

### Create an API Key

Please follow the official documentation [here](https://developers.google.com/maps/documentation/android-sdk/get-api-key#creating-api-keys) to create your own Google API Key.

### Add the API Key

Please follow the official documentation [here](https://developers.google.com/maps/documentation/android-sdk/get-api-key#add_key) to add the API Key to your application project.

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), the Driver Data UI module must also be manually initialized.

Then, to initialize the module in your app, you must call the initialization method in `onCreate` method of your Application class:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun initialize()
```

{% endtab %}
{% endtabs %}

### Override colors and texts

To override colors and texts in Driver Data UI SDK, see [Common UI configuration.](/common-ui/android/get-started)&#x20;

### 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.

{% hint style="warning" %}
The value `SPEEDING` can be set only if this configuration is enabled for your API key.
{% endhint %}

The main theme can be configured calling the following method:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun configureTripData(tripData: TripData)
```

{% endtab %}
{% endtabs %}

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`.

{% hint style="warning" %}
The value `SPEEDING` can be set only if this configuration is activated on your team.
{% endhint %}

Map items can be configured by calling the following method:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun configureMapItems(mapItems: List<MapItem>)
```

{% endtab %}
{% endtabs %}

The default value is:

`[SAFETY, ECODRIVING, DISTRACTION, SPEEDING, INTERACTIVE_MAP, SYNTHESIS]`

{% hint style="info" %}
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.
{% endhint %}

<figure><img src="/files/ZAnPYOzIx5vKZTmO4Xhi" alt=""><figcaption><p>Trip map items</p></figcaption></figure>

#### Display fragment

To show fragment in your activity, you just have to create an instance of `TripListFragment` with the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriverDataUI.createTripListFragment()
```

{% endtab %}

{% tab title="Java" %}

```
DriverDataUI.INSTANCE.createTripListFragment();
```

{% endtab %}
{% endtabs %}

and then show it using a `FragmentManager`.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
supportFragmentManager.beginTransaction()
    .replace(R.id.container, DriverDataUI.createTripListFragment())
    .commit()
```

{% endtab %}

{% tab title="Java" %}

```
getSupportFragmentManager().beginTransaction()
    .replace(R.id.container, DriverDataUI.INSTANCE?.createTripListFragment())
    .commit();

```

{% endtab %}
{% endtabs %}


# 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.&#x20;

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`:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun enableDeleteTrip(enableDeleteTrip: Boolean)
```

{% endtab %}
{% endtabs %}

## 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`:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun dayTripDescendingOrder(dayTripDescendingOrder: Boolean)
```

{% endtab %}
{% endtabs %}

## 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`:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun enableAdviceFeedback(enableAdviceFeedback: Boolean)
```

{% endtab %}
{% endtabs %}

<figure><img src="/files/ST1K4JkuXSjmuYfzp48G" alt=""><figcaption><p>Eco-driving advice</p></figcaption></figure>

## 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.<br>

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun enableAlternativeTrips(enableAlternativeTrips: Boolean)
```

{% endtab %}
{% endtabs %}

<figure><img src="/files/RmgFf5hpRJYzmXTGjhdV" alt=""><figcaption><p>Alternative transportation mode list</p></figcaption></figure>


# 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.

<figure><img src="/files/P6AcXyzBetGtuH07Q8jn" alt=""><figcaption></figcaption></figure>

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:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun getLastTripsSynthesisCardsView(
    synthesisCards: List<LastTripsSynthesisCard> = listOf(
        LastTripsSynthesisCard.SAFETY,
        LastTripsSynthesisCard.DISTRACTION,
        LastTripsSynthesisCard.ECO_DRIVING,
        LastTripsSynthesisCard.SPEEDING
    ), listener: SynthesisCardsViewListener
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
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.
{% endhint %}

{% hint style="warning" %}
The value `SPEEDING` can be set only if this configuration is enabled for your API key.
{% endhint %}

## Last trip widget

The Driver Data component includes a widget to display a short chronological list of the driver's last trips.

<figure><img src="/files/x5DzwGV0h6yIG6MsBRCK" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/KVbxJbeyu1cktm9cUlcA" alt=""><figcaption></figcaption></figure>

​​To include the last trip widget into your app, call the following method:

{% tabs %}
{% tab title="DriverDataUI" %}

```kotlin
fun getLastTripsView(
    headerDay: HeaderDay = HeaderDay.DISTANCE,
    lastTripMaxNumber: Int = 10
): Fragment {
```

{% endtab %}
{% endtabs %}

And embed the returned view into your layout.


# 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 ;&#x20;
* 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.

<figure><img src="/files/hu9bcQbom5BodD9Mfmg7" alt=""><figcaption></figcaption></figure>

​​To display the “My Synthesis” screen into your app, call the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitNavigationController.driverDataUIEntryPoint?.startMySynthesisActivity(context)
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startMySynthesisActivity(context);
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="DriverKitUI" %}

```kotlin
var scores: List<DKScoreType> = DKScoreType.values().toList()
```

{% endtab %}
{% endtabs %}

Default and accepted values are:

```
[SAFETY, ECO_DRIVING, DISTRACTION, SPEEDING]
```

{% hint style="warning" %}
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.
{% endhint %}


# 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.

<figure><img src="/files/VnE6ZRm61E5nOTml0rL9" alt=""><figcaption><p>My Driver Profile 2 screens</p></figcaption></figure>

## 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:&#x20;

* the annual distance driven per year&#x20;
* the mobility area that includes 90% of the driver’s trips,
* the percentage of weeks during which the driver has used his vehicle,.,&#x20;
* the regularity based on the relative standard deviations of the weekly distance and trip number.
* the main driving context.

<figure><img src="/files/XXbp5vQh43W2al9SxOEX" alt=""><figcaption><p>Driver's profile cards</p></figcaption></figure>

### 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.

<figure><img src="/files/GjJ7Uj5hqElUuZh81EK7" alt=""><figcaption><p>Distance estimation cards</p></figcaption></figure>

### Driver’s usual trip

The purpose of this section is to highlight the driver's most common trip in terms of duration and distance.

<figure><img src="/files/USug2ZEkoVIQ2KiRixUc" alt=""><figcaption><p>Driver's usual trip</p></figcaption></figure>

{% hint style="info" %}
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.
{% endhint %}

​​To include the “Driver Profile” screen into your app, call the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitNavigationController.driverDataUIEntryPoint?.startDriverProfileActivity(context)
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startDriverProfileActivity(context);
```

{% endtab %}
{% endtabs %}

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.

<figure><img src="/files/xCNKJdwzSVXqFlHfZqdA" alt=""><figcaption><p>Driving conditions screen</p></figcaption></figure>

If you want to include the “Driving Conditions” screen into your app as a standalone screen, call the following method:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitNavigationController.driverDataUIEntryPoint?.startDrivingConditionsActivity(context)
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitNavigationController.INSTANCE.getDriverDataUIEntryPoint().startDrivingConditionsActivity(context);
```

{% endtab %}
{% endtabs %}

And present the returned view controller using your app’s navigation API.


# 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:&#x20;

1. weekly average history
2. monthly average history

<figure><img src="/files/6iQHOCNLnofio1hG1o6u" alt=""><figcaption><p>Timeline UI - main screen</p></figcaption></figure>

## 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 :&#x20;

* Number of accelerations per 100 km
* number of brakings per 100 km
* Adherence limits per 100 km

🌿 Eco-driving sub-scores:&#x20;

* Acceleration score
* Deceleration score
* Speed maintain score
* Fuel consumption (in l)
* Achievable fuel savings (in l)
* CO2 mass (in kg)

📱Distraction sub-scores:&#x20;

* 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

<figure><img src="/files/nvhuxegcMqoxChHKN9sW" alt=""><figcaption><p>Timeline UI - Score detail screen</p></figcaption></figure>


# iOS


# Get started

## Prerequisite

Before starting DriveKit Timeline UI integration, make sure that you have initialized [Driver Data](https://docs.drivequant.com/driver-data/ios/get-started) and[ Common UI](https://docs.drivequant.com/common-ui/ios/get-started) modules.

## Integration

To add the Timeline UI module to your app using **Swift Package Manager**, add `DriveKitDriverDataTimelineUI` from repository: `https://github.com/DriveQuantPublic/drivekit-ui-ios.git` as dependency.

{% hint style="info" %}
On[ this Github repository](https://github.com/DriveQuantPublic/drivekit-ui-ios), 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.
{% endhint %}

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-the-sdk), the Timeline UI module must also be manually initialized. In the application's AppDelegate file, import `DriveKitDriverDataTimelineUI`:

```swift
import DriveKitDriverDataTimelineUI
```

Then, to initialize Timeline UI module in your app, you must call the initialization method in `didFinishLaunchingWithOptions` method of your AppDelegate:

```swift
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:

```swift
DriveKitUI.shared.scores = [.safety, .ecoDriving, .distraction, .speeding]
```

Default and accepted values:

\[ `.safety`, `.ecoDriving`, `.distraction`, `.speeding` ]

{% hint style="warning" %}
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.
{% endhint %}


# Android


# Get started

## Prerequisite

Before starting DriveKit Timeline UI integration, make sure that you have initialized [Driver Data](https://docs.drivequant.com/driver-data/android/get-started) and[ Common UI](https://docs.drivequant.com/common-ui/android/get-started) modules.

## Integration

To add Timeline UI module to your app, add the following line to your dependencies in your application build.gradle file:

```gradle
dependencies {
    implementation 'com.drivequant.drivekit:drivekit-timeline-ui:$drivekitui_version'
}
```

{% hint style="info" %}
Replace $drivekitui\_version with the DriveKit version you are using in your app
{% endhint %}

{% hint style="info" %}
On[ this Github repository](https://github.com/DriveQuantPublic/drivekit-ui-android), 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.
{% endhint %}

## Initialization

If you have [disabled the SDK auto-initialization](/get-started-drivekit/android/advanced-configurations#manually-initialize-the-sdk), the Timeline UI module must also be manually initialized.

Then, to initialize the module in your app, you must call the initialization method in `onCreate` method of your Application class:

{% tabs %}
{% tab title="DriveKitDriverDataTimelineUI" %}

```kotlin
fun initialize()
```

{% endtab %}
{% endtabs %}

## 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:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
DriveKitUI.scores = listOf(
   DKScoreType.SAFETY,
   DKScoreType.ECO_DRIVING,
   DKScoreType.DISTRACTION,
   DKScoreType.SPEEDING
)
```

{% endtab %}

{% tab title="Java" %}

```java
DriveKitUI.INSTANCE.setScores(Arrays.asList(
       DKScoreType.SAFETY,
       DKScoreType.ECO_DRIVING,
       DKScoreType.DISTRACTION,
       DKScoreType.SPEEDING)
);
```

{% endtab %}
{% endtabs %}

Default and accepted values:

\[ `SAFETY`, `ECO_DRIVING`, `DISTRACTION`, `SPEEDING` ]

{% hint style="warning" %}
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.
{% endhint %}


# 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.&#x20;

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.

{% hint style="info" %}
We recommend you to test this component in the [DriveKit Demo App](/#the-drivekit-demo-app) before you integrate it in your application.
{% endhint %}


# iOS


# Get started

## **Prerequisite**

Before starting DriveKit Vehicle integration, make sure that you have [initialized DriveKit](https://docs.drivequant.com/get-started-drivekit/ios), especially if you have [disable the SDK auto-initialization](/get-started-drivekit/ios/advanced-configurations#manually-initialize-the-sdk)**.**

{% hint style="danger" %}
If you use DriveKit Vehicle without having initialized DriveKit, the SDK may not work properly in your application.
{% endhint %}

## **Integration**

### **Get framework**&#x20;

To add the Vehicle module to your app using **Swift Package Manager**, add `DriveKitVehicle` from repository: `https://github.com/DriveQuantPublic/drivekit-sdk-spm.git` as dependency.

### **TripAnalysis configuration overload**

The configuration of the Vehicle SDK and its vehicles can overload the auto start configuration of the TripAnalysis SDK. To do this, you should call this method after the SDK Vehicle initialization:

```swift
DriveKitTripAnalysis.shared.setVehiclesConfigTakeover(vehiclesConfigTakeOver: true)
```


# Vehicle management

DriveKit Vehicle component manages cars and trucks vehicles.

{% hint style="info" %}
Methods presented in this part are available in the `DriveKitVehicle` class
{% endhint %}

## Create a custom vehicle

It is possible to create a custom vehicle from your own data. Create your vehicle using the method:

```swift
func createCustomVehicle(
    characteristics: DKVehicleCharacteristics,
    name: String? = nil,
    id: String,
    completionHandler: @escaping (DKVehicleManagerStatus, DKVehicle?) -> Void
)
```

Each vehicle will have a unique identifier and this unique ID will be added into the trip synchronization response.

This method have the following parameters:

| Name            | Type                                                                             | Description                                                                                  |
| --------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| characteristics | [DKVehicleCharacteristics](/vehicle/ios/references-ios#dkvehiclecharacteristics) | Characteristics of the vehicle you want to create. Model is detailed in the References part. |
| name            | String                                                                           | The name of the vehicle you want to create                                                   |
| id              | String                                                                           | The unique identifier of the vehicle you want to create                                      |

Check the `DKVehicleManagerStatus` value to ensure your vehicle is correctly created:

| Value                    | Description                                                                                                                                                      |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| success                  | Vehicle is successfully created and saved in the local database.                                                                                                 |
| invalidCharacteristics   | Vehicle is not created and **not** saved in the local database because provided characteristics are not valid.                                                   |
| vehicleIdAlreadyUsed     | Vehicle is not created and **not** saved in the local database because the provided vehicleId already exists.                                                    |
| onlyOneGpsVehicleAllowed | This value is not returned for this service.                                                                                                                     |
| error                    | <p>Vehicle is not created and <strong>not</strong> saved in the local database because there was an unexpected error.</p><p>e.g: User not logged to DriveKit</p> |

[DKVehicle](/vehicle/ios/references-ios#dkvehicle) model is described in the References part.

## **Synchronize vehicle list**

You can retrieve the user’s vehicle list from the DriveQuant servers by calling the following method:

```swift
func getVehiclesOrderByNameAsc(
    type: DKVehicleSynchronizationType = .defaultSync, 
    completionHandler: @escaping (DKVehicleSyncStatus, [DKVehicle]) -> Void
) 
```

This method have the following parameter:

<table><thead><tr><th width="170.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td>DKVehicleSynchronizationType</td><td><p>Can be <code>defaultSync</code> or <code>cache</code>.</p><p>- <code>defaultSync</code> will synchronize the vehicles by calling the DriveQuant servers</p><p>- <code>cache</code> will retrieve the vehicles already synchronized in the local database.</p></td></tr></tbody></table>

[DKVehicleSyncStatus](/vehicle/ios/references-ios#dkvehiclesyncstatus) and [DKVehicle](/vehicle/ios/references-ios#dkvehicle) models are described in the References part.

## **Retrieve local vehicle list**

You can retrieve the list of vehicles stored in the DriveKit local database by calling the previous method but with the type parameter to `.cache`.

## **Replace a vehicle**

Instead of deleting and then creating a new vehicle, you can use only one method to replace an existing vehicle.

{% hint style="info" %}
A previously paired beacon to that vehicle is automatically paired to the new vehicle.
{% endhint %}

### **Replace a car**

```swift
func replaceWithCarVehicle(
        oldVehicleId: String,
        characteristics: DKCarVehicleCharacteristics,
        name: String? = nil,
        liteConfig: Bool = false,
        completionHandler: @escaping (DKVehicleReplaceStatus, DKVehicle?) -> Void
)
```

This method have the following parameters:

| Name            | Type                                                                                   | Description                                              |
| --------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| oldVehicleId    | String                                                                                 | The unique identifier of the car you want to replace     |
| characteristics | [DKCarVehicleCharacteristics](/vehicle/ios/references-ios#dkcarvehiclecharacteristics) | Characteristics of the car you want to create            |
| name            | String                                                                                 | The name of the car                                      |
| liteConfig      | Boolean                                                                                | Advanced configuration. Leave this parameter as `false`. |

[DKVehicleReplaceStatus](/vehicle/ios/references-ios#dkvehiclereplacestatus) and [DKVehicle](/vehicle/ios/references-ios#dkvehicle) models are described in the References part.

**Replace a truck**

```swift
func replaceWithTruckVehicle(
        oldVehicleId: String,
        characteristics: DKTruckVehicleCharacteristics,
        name: String? = nil,
        completionHandler: @escaping (DKVehicleReplaceStatus, DKVehicle?) -> Void
)
```

This method have the following parameters:

<table><thead><tr><th width="221.33333333333331">Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>oldVehicleId</td><td>String</td><td>The unique identifier of the truck you want to replace</td></tr><tr><td>characteristics</td><td><a href="/pages/emVdreTs9oK5wf722cPq#dktruckvehiclecharacteristics">DKTruckVehicleCharacteristics</a></td><td>Characteristics of the truck you want to create</td></tr><tr><td>name</td><td>String</td><td>The name of the truck</td></tr></tbody></table>

[DKVehicleReplaceStatus](/vehicle/ios/references-ios#dkvehiclereplacestatus) and [DKVehicle](/vehicle/ios/references-ios#dkvehicle) models are described in the References part.

## **Delete a vehicle**

{% hint style="info" %}
When you delete a vehicle, a previously paired beacon or Bluetooth device to that vehicle is automatically unpaired and released from the vehicle. By this way, you can immediately pair the beacon or the Bluetooth device to another vehicle.
{% endhint %}

To delete a vehicle, you have to call the following method:

```swift
func deleteVehicle(
    vehicleId: String,
    completionHandler: @escaping (DKVehicleManagerStatus) -> Void
)
```

This method have the following parameter:

| Name      | Type   | Description                                            |
| --------- | ------ | ------------------------------------------------------ |
| vehicleId | String | The identifier of the vehicle that you want to delete. |

Check the `DKVehicleManagerStatus` value to ensure your vehicle is successfully deleted:

| Value                    | Description                                                                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| success                  | Vehicle is successfully deleted and changes are saved in the local database.                                                               |
| unknownVehicle           | The specified vehicle could not be deleted because the vehicle id is not a vehicle or belongs to another user account.                     |
| invalidCharacteristics   | *This value is not returned for this service.*                                                                                             |
| vehicleIdAlreadyUsed     | *This value is not returned for this service.*                                                                                             |
| onlyOneGpsVehicleAllowed | *This value is not returned for this service.*                                                                                             |
| error                    | <p>Vehicle is not deleted and changes are not saved in the local database because there was an unexpected error.</p><p>e.g: No network</p> |

## **Rename a vehicle**

To rename a vehicle, you have to call the following method:

```swift
func renameVehicle(
    name: String,
    vehicleId: String,
    completionHandler: @escaping (DKVehicleManagerStatus) -> Void
) 
```

This method have the following parameters:

| Name      | Type   | Description                                           |
| --------- | ------ | ----------------------------------------------------- |
| name      | String | The new name for the vehicle                          |
| vehicleId | String | The identifier of the vehicle that you want to rename |

Check the `DKVehicleManagerStatus` value to ensure your vehicle is successfully deleted:

| Value                    | Description                                                                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| success                  | Vehicle is successfully renamed and changes are saved in the local database.                                                               |
| unknownVehicle           | The specified vehicle could not be renamed because the vehicle id is not valid.                                                            |
| invalidCharacteristics   | *This value is not returned for this service.*                                                                                             |
| vehicleIdAlreadyUsed     | *This value is not returned for this service.*                                                                                             |
| onlyOneGpsVehicleAllowed | *This value is not returned for this service.*                                                                                             |
| error                    | <p>Vehicle is not renamed and changes are not saved in the local database because there was an unexpected error.</p><p>e.g: No network</p> |

## **Change the detection mode of a vehicle**

When you have a vehicle, it is necessary to set its DetectionMode type. The following function is used to select the DetectionMode of a vehicle:

```swift
func updateDetectionMode(
    vehicleId: String,
    detectionMode: DKDetectionMode,
    forceGPSVehicleUpdate: Bool = false,
    completionHandler: @escaping (DKDetectionModeStatus) -> Void
)
```

This method have the following parameters:

<table><thead><tr><th width="239.33333333333331">Name</th><th width="174">Type</th><th>Description</th></tr></thead><tbody><tr><td>vehicleId</td><td>String</td><td>The vehicle which you want to update the DetectionMode</td></tr><tr><td>detectionMode</td><td><a href="/pages/emVdreTs9oK5wf722cPq#dkdetectionmode">DKDetectionMode</a></td><td>The detection mode you want for the vehicle</td></tr><tr><td>forceGPSVehicleUpdate</td><td>Boolean</td><td><p>Optional parameter to force the <em>GPS</em> detection mode for a new vehicle if there is already a vehicle with this mode.</p><p>The default setting is false. In this case, the response of this service request will be <code>gpsModeAlreadyExists</code> and the new vehicle will not be configured in <em>GPS</em> mode. If this setting is true, the vehicle will inherit the <em>GPS</em> trigger mode and the existing vehicle that had this mode will be switched to the <code>.disabled</code> mode.</p></td></tr></tbody></table>

[DKDetectionModeStatus](/vehicle/ios/references-ios#dkdetectionmodestatus) model is described in the References part.

{% hint style="warning" %}
Information: If a driver has more than one vehicle, only one can be configured in `GPS` mode. If you choose a `GPS` trigger mode for a vehicle while there is already another vehicle with this trigger mode, then you must specify the appropriate action with the `forceGPSVehicleUpdate` parameter to `true`. The other vehicle will have its detection mode updated to `.disabled`.
{% endhint %}

## Get Vehicle Last Location

This function returns the location of the end of the last trip for a given vehicle.&#x20;

The returned location type is [DKTripLocation](/trip-analysis/ios/references#dktriplocation)

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

```swift
func getVehicleLocation(_ vehicleId: String) -> DKTripLocation?
```

## Get Vehicle Timeline

Each time a trip is analyzed for a given vehicle, some data are aggregated in its timeline.

To get the timeline for a given vehicle, you have to call the following method:

```swift
public func getTimeline(
        vehicleId: String,
        periods: [DKPeriod],
        type: SynchronizationType = .defaultSync,
        completionHandler: @escaping (TimelineSyncStatus, [DKVehicleTimeline]?) -> Void)

```

This method have the following parameters:

<table><thead><tr><th width="187">Name</th><th width="195">Type</th><th>Description</th></tr></thead><tbody><tr><td>vehicleId</td><td>String</td><td>The unique identifier of the driver’s vehicle.</td></tr><tr><td>periods</td><td>[<code>DKPeriod</code>]</td><td><p>Get timeline data in a specific period of time.</p><p>Possible values are : <code>.week,</code> <code>.month</code>, <code>.year</code></p></td></tr><tr><td>synchronizationType</td><td><code>SynchronizationType</code></td><td><p>Define the source of the timelines data you want to retrieve.<br><br>Possible values are:<br><code>.cache</code>: No sync will be performed and the data retrieved during the last sync will be returned via the completionHandler.</p><p><code>.defaultSync</code>: the SDK will try to synchronize timelines with DriveQuant backend and then return them via the <code>completionHandler</code>.</p></td></tr></tbody></table>

The `TimelineSyncStatus` enum values are:

<table><thead><tr><th width="243">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>Synchronization has been successfully performed</td></tr><tr><td>drivekitNotInitialized</td><td>DriveKit has not been initialized yet.</td></tr><tr><td>userNotConnected</td><td>No authenticated user was found.</td></tr><tr><td>vehicleNotFound</td><td>The identifier of the vehicle passed as parameter is not associated with any of the user's vehicles.</td></tr><tr><td>timelineNotFound</td><td><p>There was no timeline for the related vehicle.</p><p>This rare situation occurs only if the vehicle was created several years ago and has not yet analyzed trips.</p></td></tr><tr><td>cacheDataOnly</td><td><code>SynchronizationType</code> has been set to <code>.cache</code>.</td></tr><tr><td>failedToSyncTimelineCacheOnly</td><td>Synchronization has failed, only data retrieved during the last sync are returned.</td></tr></tbody></table>

The second argument in the `completionHandler` is a list of `DKVehicleTimeline` object, one per requested period.

`DKVehicleTimeline` model is described in the [References](/vehicle/ios/references-ios#dkvehicletimeline) part.


# Beacon management

## **Pair a beacon to a vehicle**

The following function allows you to create a logical pairing between a beacon and a vehicle. The results of data analysis containing a beacon will be assigned to the vehicle to which the beacon has been paired with.

```swift
func addBeacon(
    vehicleId: String,
    beacon: DKBeacon,
    completionHandler: @escaping (DKVehicleBeaconStatus) -> Void
)
```

This method have the following parameters:

<table><thead><tr><th width="165.33333333333331">Name</th><th width="151">Type</th><th>Description</th></tr></thead><tbody><tr><td>beacon</td><td><a href="/pages/emVdreTs9oK5wf722cPq#dkbeacon">DKBeacon</a></td><td>The beacon data you want to pair to the vehicle</td></tr><tr><td>vehicleId</td><td>String</td><td>The identifier of vehicle that you wish to pair with a beacon</td></tr></tbody></table>

remark: All fields are required. If you don't know the uniqueId of your beacons, just add an empty field.

Check the `DKVehicleBeaconStatus` value to ensure your beacon is correctly paired:

<table><thead><tr><th width="257">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The beacon has been successfully paired to the specified vehicle. The vehicle data in the local database is automatically updated.</td></tr><tr><td>error</td><td>An error occurred when trying to pair the beacon to the vehicle, for example if the user has no network during when the method is called.</td></tr><tr><td>unknownVehicle</td><td>An error occurred: the specified vehicle does not belong to the user.</td></tr><tr><td>unavailableBeacon</td><td>The provided beacon is currently paired to another vehicle. You must unpair the beacon to that vehicle before in order to pair it to your desired vehicle.</td></tr></tbody></table>

## **Replace the beacon of a vehicle**

If a beacon is already paired with a vehicle, it can be replaced. The following function is used to change the beacon paired with a vehicle:

```swift
func changeBeacon(
    vehicleId: String,
    oldVehicleId: String,
    beacon: DKBeacon,
    completionHandler: @escaping (DKVehicleBeaconStatus) -> Void
)
```

This method have the following parameters:

<table><thead><tr><th width="202.33333333333331">Name</th><th width="144">Type</th><th>Description</th></tr></thead><tbody><tr><td>beacon</td><td><a href="/pages/emVdreTs9oK5wf722cPq#dkbeacon">DKBeacon</a></td><td>The new beacon data you want to pair to the vehicle.</td></tr><tr><td>vehicleId</td><td>String</td><td>The identifier of the vehicle for which you wish to change the beacon</td></tr><tr><td>oldVehicleId</td><td>String</td><td>The identifier of the old vehicle paired to the beacon</td></tr></tbody></table>

remark: All fields are required. If you don't know the uniqueId of your beacons, just add an empty field.

Check the `DKVehicleBeaconStatus` value to ensure your beacon is correctly changed:

<table><thead><tr><th width="244">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The beacon has been successfully replaced for the specified vehicle. The vehicles data in the local database are automatically updated.</td></tr><tr><td>error</td><td>An error occurred when trying to replace the beacon of the vehicle.</td></tr><tr><td>unknownVehicle</td><td>An error occurred: the specified vehicle does not belong to the user.</td></tr><tr><td>unavailableBeacon</td><td>The provided beacon is currently paired to another vehicle. You must unpair the beacon to that vehicle before in order to pair it to your desired vehicle.</td></tr></tbody></table>

## **Unpair the beacon from a vehicle**

The following function can be used to delete the pairing between a beacon and a vehicle:

```swift
func removeBeacon(
    vehicleId: String,
    completionHandler: @escaping (DKVehicleBeaconRemoveStatus) -> Void
)
```

This method have the following parameter:

<table><thead><tr><th width="173.33333333333331">Name</th><th width="137">Type</th><th>Description</th></tr></thead><tbody><tr><td>vehicleId</td><td>String</td><td>The identifier of the vehicle for which you want to unpair the beacon.</td></tr></tbody></table>

Check the `DKVehicleBeaconRemoveStatus` value to ensure your beacon is correctly unpaired:

<table><thead><tr><th width="286">Value</th><th>Description</th></tr></thead><tbody><tr><td>success</td><td>The beacon has been successfully removed from the specified vehicle. The vehicle data in the local database is automatically updated.</td></tr><tr><td>error</td><td>An error occurred when trying to remove the beacon of the vehicle.</td></tr><tr><td>unknownVehicle</td><td>An error occurred: the specified vehicle does not belong to the user.</td></tr></tbody></table>


# Bluetooth device management

{% hint style="info" %}
Methods presented in this part are available in the `DriveKitVehicle` class
{% endhint %}

## Pair a Bluetooth device to a vehicle

The following method allows you to create a logical pairing between a Bluetooth device and a vehicle. The results of data analysis containing a Bluetooth device will be assigned to the vehicle to which the peripheral has been paired with.

```swift
func addBluetooth(
	vehicleId: String, 
	bluetooth: DKBluetooth, 
	completionHandler: @escaping (DKVehicleBluetoothStatus) -> Void
)
```

This method have the following parameters:

| Name      | Type                                                   | Description                                                                    |
| --------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ |
| bluetooth | [DKBluetooth](/vehicle/ios/references-ios#dkbluetooth) | Bluetooth device information.                                                  |
| vehicleId | String                                                 | The identifier of the vehicle that you wish to pair with the Bluetooth device. |

\
[DKVehicleBluetoothStatus](/vehicle/ios/references-ios#dkvehiclebluetoothstatus) model is described in the References part.

## **Remove the Bluetooth device from a vehicle**

The following function can be used to delete the pairing between a Bluetooth device and a vehicle:

```swift
func removeBluetooth(
    vehicleId: String,
    completionHandler: @escaping (DKVehicleBluetoothRemoveStatus) -> Void
)
```

This method have the following parameter:

| Name      | Type   | Description                                                                      |
| --------- | ------ | -------------------------------------------------------------------------------- |
| vehicleId | String | The identifier of the vehicle that you wish to unpair with the Bluetooth device. |

[DKVehicleRemoveBluetoothStatus](/vehicle/ios/references-ios#dkvehiclebluetoothremovestatus) model is described in the References part.


# Odometer

{% hint style="info" %}
Methods presented in this part are available in the `DriveKitVehicle` class
{% endhint %}

## Synchronize vehicle's odometer

You can retrieve the vehicle’s odometer data from the DriveQuant servers by calling the following method:

```swift
func getOdometer(
	vehicleId: String, 
	type: DKVehicleSynchronizationType = .defaultSync, 
	completionHandler: @escaping (DKOdometerSyncStatus, DKVehicleOdometer?, [DKVehicleOdometerHistory]?) -> Void
)
```

This method have the following parameters:

<table><thead><tr><th width="165.33333333333331">Name</th><th width="206">Type</th><th>Description</th></tr></thead><tbody><tr><td>vehicleId</td><td>String</td><td>The vehicle for which you want to get the odometer’s data</td></tr><tr><td>type</td><td>SynchronizationType</td><td><p>Can be <code>defaultSync</code> or <code>cache</code>.</p><p>- <code>defaultSync</code> will synchronize the vehicle’s odometer by calling the DriveQuant servers</p><p>- <code>cache</code> will retrieve the odometer data already synchronized in the local database.</p></td></tr></tbody></table>

[DKOdometerSyncStatus](/vehicle/ios/references-ios#dkodometersyncstatus), [DKVehicleOdometer](/vehicle/ios/references-ios#dkvehicleodometer) and [DKVehicleOdometerHistory](/vehicle/ios/references-ios#dkvehicleodometerhistory) models are described in the References part.

## **Retrieve local vehicle’s odometer data**

You can retrieve the vehicle’s odometer data stored in the DriveKit local database by calling the previous method but with the type parameter to `cache`.

## **Add odometer history**

You can add a new entry to a vehicle’s odometer by calling the following method:

```swift
func addOdometerHistory(
    vehicleId: String,
    distance: Double,
    completionHandler: @escaping (DKOdometerAddHistoryStatus, DKVehicleOdometer?, [DKVehicleOdometerHistory]?) -> Void
)
```

This method have the following parameters:

| Name      | Type   | Description                                               |
| --------- | ------ | --------------------------------------------------------- |
| vehicleId | String | The vehicle id for which you want to add an history entry |
| distance  | Double | The distance in km you want to set                        |

[DKOdometerAddHistoryStatus](/vehicle/ios/references-ios#dkodometeraddhistorystatus), [DKVehicleOdometer](/vehicle/ios/references-ios#dkvehicleodometer) and [DKVehicleOdometerHistory](/vehicle/ios/references-ios#dkvehicleodometerhistory) models are described in the References part.

## Update odometer history

To update an entry to a vehicle’s odometer, call the following method:

```swift
func updateOdometerHistory(
    vehicleId: String,
    historyId: String,
    distance: Double,
    completionHandler: @escaping (DKOdometerUpdateHistoryStatus, DKVehicleOdometer?, [DKVehicleOdometerHistory]?) -> Void
)
```

This method have the following parameters:

| Name      | Type   | Description                                                     |
| --------- | ------ | --------------------------------------------------------------- |
| vehicleId | String | The vehicle id for which you want to update the odometer’s data |
| historyId | String | The history id for which you want to update the distance.       |
| distance  | Double | The distance in km you want to update                           |

[DKOdometerUpdateHistoryStatus](/vehicle/ios/references-ios#dkodometerupdatehistorystatus), [DKVehicleOdometer](/vehicle/ios/references-ios#dkvehicleodometer) and [DKVehicleOdometerHistory](/vehicle/ios/references-ios#dkvehicleodometerhistory) models are described in the References part.

## Delete odometer history

To delete vehicle’s odometer entry, call the following method:

```swift
func deleteOdometerHistory(
    vehicleId: String,
    historyId: String,
    completionHandler: @escaping (DKOdometerDeleteHistoryStatus, DKVehicleOdometer?, [DKVehicleOdometerHistory]?) -> Void
)
```

This method have the following parameters:

| Name      | Type   | Description                                                              |
| --------- | ------ | ------------------------------------------------------------------------ |
| vehicleId | String | The vehicle id for which you want to delete the odometer’s history entry |
| historyId | String | The history id you want to delete                                        |

[DKOdometerDeleteHistoryStatus](/vehicle/ios/references-ios#dkodometerdeletehistorystatus), [DKVehicleOdometer](/vehicle/ios/references-ios#dkvehicleodometer) and [DKVehicleOdometerHistory](/vehicle/ios/references-ios#dkvehicleodometerhistory) models are described in the References part.




---

[Next Page](/llms-full.txt/1)

