> For the complete documentation index, see [llms.txt](https://docs.sentiance.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sentiance.com/implementing-features/insights/driving-insights.md).

# Driving Insights

{% hint style="info" %}
To learn about the Driving Insights feature, check out [this page](/getting-started/features-catalog/driving-insights.md).
{% endhint %}

## Prerequisites

The Driving Insights feature relies on additional library dependencies alongside the core SDK dependency. To start using this feature, you must first add these dependencies to you project.

<details>

<summary>iOS</summary>

This feature is included in the main SDK framework. No additional dependencies are needed.

</details>

<details>

<summary>Android</summary>

Open your app <mark style="color:$success;">**`build.gradle`**</mark> file and add the driving insights dependency.

{% code title="app/build.gradle" %}

```kotlin
dependencies {
    implementation(platform('com.sentiance:sdk-bom:<sentiance-version>'))
    implementation('com.sentiance:sdk-driving-insights')
}
```

{% endcode %}

</details>

<details>

<summary>React Native</summary>

This feature is included after installing the following modules:

* [@sentiance-react-native/core](https://www.npmjs.com/package/@sentiance-react-native/core)
* [@sentiance-react-native/event-timeline](https://www.npmjs.com/package/@sentiance-react-native/event-timeline)
* [@sentiance-react-native/driving-insights](https://www.npmjs.com/package/@sentiance-react-native/driving-insights)

</details>

<details>

<summary>Flutter</summary>

This feature can be added by installing the following packages:

* [sentiance\_core](https://pub.dev/packages/sentiance_core)
* [sentiance\_event\_timeline](https://pub.dev/packages/sentiance_event_timeline)
* [sentiance\_driving\_insights](https://pub.dev/packages/sentiance_driving_insights)

</details>

## Utilize the Driving Insights APIs

In this section, you can find examples of how to query the Sentiance SDK for driving insights, safe driving scores, detailed driving events. You will also find how to register to be notified of driving insights, once it becomes available.

### Query for Driving Insights

{% hint style="info" %}
Driving Insights become available a few minutes after a transport ends. Once the user stops driving, the SDK takes a few minutes to make sure that the drive is over, and then proceeds to prepare the insights.

To be notified of when the insights are ready, you can [subscribe for Driving Insights updates](#subscribe-for-driving-insights-updates).
{% endhint %}

To retrieve driving insights, use the <mark style="color:$success;">**`getDrivingInsights`**</mark> method.&#x20;

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

```swift
let sentiance = Sentiance.shared
if let drivingInsights = sentiance.getDrivingInsights(forTransportId: transportId) {
    let event = drivingInsights.transportEvent
    let safetyScores = drivingInsights.safetyScores
    
    print("Focus score: \(safetyScores.focusScore ?? -1)")
    print("Legal score: \(safetyScores.legalScore ?? -1)")
    print("Smooth score: \(safetyScores.smoothScore ?? -1)")
    print("Call-while-moving score: \(safetyScores.callWhileMovingScore ?? -1)")
    print("Overall score: \(safetyScores.overallScore ?? -1)")

    print("Event ID: \(event.eventId)")
    print("Started on: \(event.startDate)")
    print("Ended on: \(String(describing: event.endDate))")
    print("Mode: \(event.transportMode)")

    if let distanceInMeters = event.distanceInMeters {
        print("Distance: \(distanceInMeters)")
    }

    print("Waypoints: \(event.waypoints)")
}
```

{% endtab %}

{% tab title="Android" %}

```kotlin
val drivingInsightsApi = DrivingInsightsApi.getInstance(context)
val drivingInsights = drivingInsightsApi.getDrivingInsights(transportId)
if (drivingInsights != null) {
    val event = drivingInsights.transportEvent
    val safetyScores = drivingInsights.safetyScores

    print("Focus score: ${safetyScores.focusScore}")
    print("Legal score: ${safetyScores.legalScore}")
    print("Smooth score: ${safetyScores.smoothScore}")
    print("Call-while-moving score: ${safetyScores.callWhileMovingScore}")
    print("Overall score: ${safetyScores.overallScore}")

    print("Event ID: ${event.id}")
    print("Started on: ${event.startTime}")
    print("Ended on: ${event.endTime}")
    print("Mode: ${event.transportMode}")

    if (event.distanceInMeters != null) {
        print("Distance: ${event.distanceInMeters}")
    }

    print("Waypoints: ${event.waypoints}")
}
```

{% endtab %}

{% tab title="React Native" %}

```javascript
import SentianceDrivingInsights from "@sentiance-react-native/driving-insights";

const drivingInsights = await SentianceDrivingInsights.getDrivingInsights(transportId);

if (drivingInsights !== null) {
    const event = drivingInsights.transportEvent; 
    const safetyScores = drivingInsights.safetyScores;
    
    if (safetyScores.focusScore) {
        console.log(`Focus score: ${safetyScores.focusScore}`);
    }
    if (safetyScores.legalScore) {
        console.log(`Legal score: ${safetyScores.legalScore}`);
    }
    if (safetyScores.smoothScore) {
        console.log(`Smooth score: ${safetyScores.smoothScore}`);
    }
    if (safetyScores.callWhileMovingScore) {
        console.log(`Call-while-moving score: ${safetyScores.callWhileMovingScore}`);
    }
    if (safetyScores.overallScore) {
        console.log(`Overall score: ${safetyScores.overallScore}`);
    }
    
    console.log(`Event ID: ${event.id}`);
    console.log(`Started on: ${event.startTime}`);
    console.log(`Ended on: ${event.endTime}`);
    console.log(`Mode: ${transport.transportMode}`);
    
    if (event.distance) {
        console.log(`Distance: ${event.distance}`);
    }
    console.log(`Waypoints: ${JSON.stringify(event.waypoints)}`);
}
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart">import 'package:sentiance_driving_insights/sentiance_driving_insights.dart';

final sentianceDrivingInsights = SentianceDrivingInsights();

<strong>void getDrivingInsightsForTransport() async {
</strong>  String transportId = "your_transport_id";
  final drivingInsights = await sentianceDrivingInsights.getDrivingInsights(transportId);
  if (drivingInsights != null) {
    final transportEvent = drivingInsights.transportEvent;
    final safetyScores = drivingInsights.safetyScores;
    
    print('Focus score: ${safetyScores.focusScore}');
    print('Legal score: ${safetyScores.legalScore}');
    print('Smooth score: ${safetyScores.smoothScore}');
    print('Call-while-moving score: ${safetyScores.callWhileMovingScore}');
    print('Overall score: ${safetyScores.overallScore}');

    print('Event ID: ${transportEvent.id}');
    print('Started on: ${transportEvent.startTimeMs}');
    print('Ended on: ${transportEvent.endTimeMs}');
    print('Last updated on: ${transportEvent.lastUpdateTimeMs}');
    print('Mode: ${transportEvent.transportMode}');
    print('Duration in seconds: ${transportEvent.durationInSeconds}');
    print('Distance: ${transportEvent.distance}');
    print('Waypoints: [${transportEvent.waypoints.map((wp) => wp.toString()).join(", ")}]');
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Query For Driving Events

The Sentiance SDK offers more granular driving insights. You can retrieve detailed events, such as speeding and harsh driving, as shown below.

{% tabs %}
{% tab title="iOS" %}
{% code lineNumbers="true" %}

```swift
// Harsh driving events, used for computing the smooth driving score
Sentiance.shared.getHarshDrivingEvents(forTransportId: transportId).forEach { harshDrivingEvent in
    print("Start date: \(harshDrivingEvent.startDate)")
    print("End date: \(harshDrivingEvent.endDate)")
    print("Magnitude: \(harshDrivingEvent.magnitude)")
}

// Phone usage events, used for computing the focused driving score
Sentiance.shared.getPhoneUsageEvents(forTransportId: transportId).forEach { phoneUsageEvent in
    print("Start date: \(phoneUsageEvent.startDate)")
    print("End date: \(phoneUsageEvent.endDate)")
}

// Call-while-moving events, used for computing the call-while-moving score
Sentiance.shared.getCallsWhileMovingEvents(forTransportId: transportId).forEach { callWhileMovingEvent in
    print("Start date: \(callWhileMovingEvent.startDate)")
    print("End date: \(callWhileMovingEvent.endDate)")
    if let minSpeed = callWhileMovingEvent.minTraveledSpeedInMps?.floatValue {
        print("Min traveled speed: \(minSpeed)")
    }
    if let maxSpeed = callWhileMovingEvent.maxTraveledSpeedInMps?.floatValue {
        print("Max traveled speed: \(maxSpeed)")
    }
}

// Speeding events, used for computing the legal driving score
Sentiance.shared.getSpeedingEvents(forTransportId: transportId).forEach { speedingEvent in
    print("Start Date: \(speedingEvent.startDate)")
    print("End Date: \(speedingEvent.endDate)")
    print("Waypoints: \(speedingEvent.waypoints)")
}
```

{% endcode %}
{% endtab %}

{% tab title="Android" %}

<pre class="language-kotlin"><code class="lang-kotlin"><strong>// Harsh driving events, used for computing the smooth driving score
</strong>DrivingInsightsApi.getInstance(context).getHarshDrivingEvents(transportId)
  .forEach { harshDrivingEvent -> 
    print("Start time: ${harshDrivingEvent.startTime}")
    print("End time: ${harshDrivingEvent.endTime}")
    print("Magnitude: ${harshDrivingEvent.magnitude}")
}

// Phone usage events, used for computing the focused driving score
DrivingInsightsApi.getInstance(context).getPhoneUsageEvents(transportId)
  .forEach { phoneUsageEvent ->
    print("Start time: ${phoneUsageEvent.startTime}")
    print("End time: ${phoneUsageEvent.endTime}")
}

// Call-while-moving events, used for computing the call-while-moving score
DrivingInsightsApi.getInstance(context).getCallWhileMovingEvents(transportId)
  .forEach { callWhileMovingEvent ->
    print("Start time: ${callWhileMovingEvent.startTime}")
    print("End time: ${callWhileMovingEvent.endTime}")
    print("Min traveled speed: ${callWhileMovingEvent.minTraveledSpeedInMps}")        
    print("Max traveled speed: ${callWhileMovingEvent.maxTraveledSpeedInMps}")        
}

// Speeding events, used for computing the legal driving score
DrivingInsightsApi.getInstance(context).getSpeedingEvents(transportId)
  .forEach { speedingEvent ->
    print("Start time: ${speedingEvent.startTime}")
    print("End time: ${speedingEvent.endTime}")
    print("Waypoints: ${speedingEvent.waypoints}")
}
</code></pre>

{% endtab %}

{% tab title="React Native" %}

```javascript
import SentianceDrivingInsights from "@sentiance-react-native/driving-insights";

// Harsh driving events, used for computing the smooth driving score
const harshDrivingEvents = await SentianceDrivingInsights.getHarshDrivingEvents(transportId);
for (const event of harshDrivingEvents) {
    console.log(`Start time: ${event.startTime}`);
    console.log(`End time: ${event.endTime}`);
    console.log(`Magnitude: ${event.magnitude}`);
}

// Phone usage events, used for computing the focused driving score
const phoneUsageEvents = await SentianceDrivingInsights.getPhoneUsageEvents(transportId);
for (const event of phoneUsageEvents) {
    console.log(`Start time: ${event.startTime}`);
    console.log(`End time: ${event.endTime}`);
}

// Call-while-moving events, used for computing the call-while-moving score
const callWhileMovingEvents = await SentianceDrivingInsights.getCallWhileMovingEvents(transportId);
for (const event of callWhileMovingEvents) {
    console.log(`Start time: ${event.startTime}`);
    console.log(`End time: ${event.endTime}`);
    console.log(`Min traveled speed: ${event.minTravelledSpeedInMps}`);        
    console.log(`Max traveled speed: ${event.maxTravelledSpeedInMps}`);
}

// Speeding events, used for computing the legal driving score
const speedingEvents = await SentianceDrivingInsights.getSpeedingEvents(transportId);
for (const event of speedingEvents) {
    console.log(`Start time: ${event.startTime}`);
    console.log(`End time: ${event.endTime}`);
    console.log(`Waypoints: ${JSON.stringify(event.waypoints)}`);
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:sentiance_driving_insights/sentiance_driving_insights.dart';

final sentianceDrivingInsights = SentianceDrivingInsights();

void fetchDrivingEvents(String transportId) async {
  // Harsh driving events, used for computing the smooth driving score
  final harshDrivingEvents = await sentianceDrivingInsights.getHarshDrivingEvents(transportId);
  for (final event in harshDrivingEvents) {
    print('Start time: ${event.startTimeMs}');
    print('End time: ${event.endTimeMs}');
    print('Magnitude: ${event.magnitude}');
  }

  // Phone usage events, used for computing the focused driving score
  final phoneUsageEvents = await sentianceDrivingInsights.getPhoneUsageEvents(transportId);
  for (final event in phoneUsageEvents) {
    print('Start time: ${event.startTimeMs}');
    print('End time: ${event.endTimeMs}');
  }

  // Call-while-moving events, used for computing the call-while-moving score
  final callWhileMovingEvents = await sentianceDrivingInsights.getCallWhileMovingEvents(transportId);
  for (final event in callWhileMovingEvents) {
    print('Start time: ${event.startTimeMs}');
    print('End time: ${event.endTimeMs}');
    print('Min traveled speed: ${event.minTraveledSpeedInMps}');
    print('Max traveled speed: ${event.maxTraveledSpeedInMps}');
  }

  // Speeding events, used for computing the legal driving score
  final speedingEvents = await sentianceDrivingInsights.getSpeedingEvents(transportId);
  for (final event in speedingEvents) {
    print('Start time: ${event.startTimeMs}');
    print('End time: ${event.endTimeMs}');
    print('Waypoints: ${event.waypoints}');
  }
}
```

{% endtab %}
{% endtabs %}

### Subscribe for Driving Insights Updates

{% hint style="info" %}
Checkout [Real-time Listeners](/sdk/appendix/real-time-listeners.md) to read more about implementing the SDK's Listeners
{% endhint %}

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

```swift
class MyDelegate: DrivingInsightsReadyDelegate {
    func onDrivingInsightsReady(insights: SENTSDK.DrivingInsights) {
        let transportEvent = insights.transportEvent
        let safetyScores = insights.safetyScores
    }
}
        
Sentiance.shared.drivingInsightsReadyDelegate = MyDelegate()
```

{% endtab %}

{% tab title="Android" %}

```kotlin
val drivingInsightsApi = DrivingInsightsApi.getInstance(context)

drivingInsightsApi.setDrivingInsightsReadyListener { insights ->
    val transportEvent = insights.transportEvent
    val safetyScores = insights.safetyScores
}
```

{% endtab %}

{% tab title="React Native" %}
To get driving insights updates even when your app is in the background, place the following code inside your app's entrypoint **index.js** file. If you're only interested in these updates when your app is foregrounded, place this code inside the appropriate UI code instead.

```javascript
import SentianceDrivingInsights from "@sentiance-react-native/driving-insights";
import SentianceCore from "@sentiance-react-native/core";

await SentianceCore.ensureInitialized(); // Ensure SDK is initialized first

// If you're subscribing to updates only in the foreground, make sure
// to call subscription.remove() inside your component's componentWillUnmount() function
const subscription = await SentianceDrivingInsights.addDrivingInsightsReadyListener(drivingInsights => {
    // Handle the insights here (see the Query for Driving Insights
    // example above).
});
```

{% endtab %}

{% tab title="Flutter" %}
Create a **background.dart** file under your project's **lib** folder with the following code:

{% code title="background.dart" %}

```dart
import 'package:sentiance_driving_insights/sentiance_driving_insights.dart';
import 'package:sentiance_core/sentiance_core.dart';

@pragma('vm:entry-point')
void registerDrivingInsightsListener() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SentianceCore.ensureInitialized();
  
  SentianceDrivingInsights.registerDrivingInsightsListener((drivingInsights) {
    // Handle the insights here (see the Query for Driving Insights
    // example above).
  });
}
```

{% endcode %}

Add the following code, depending on your target platform.

For **iOS**, add the following to your app delegate class:

{% code title="AppDelegate.swift" %}

```swift
import Flutter
import sentiance_driving_insights

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
    
        // Other code
        
        // Make sure the SDK is initialized before calling this
        SentianceDrivingInsightsPlugin.initializeListener(
            withEntryPoint: "registerDrivingInsightsListener",
            libraryURI: "package:your_app_package_name/background.dart"
        )
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}
```

{% endcode %}

For **Android**, add this code to your custom application class:

{% code title="MainApplication.kt" %}

```kotlin
import android.app.Application
import com.sentiance.driving_insights_plugin.DrivingInsightsPlugin

class MainApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        // Other code
        
        val dartLibrary = "package:your_app_package_name/background.dart"
        // Make sure the SDK is initialized before calling this
        DrivingInsightsPlugin.initializeListener(this, dartLibrary, "registerDrivingInsightsListener")
    }
}
```

{% endcode %}

{% hint style="info" %}
If you're calling other 3rd party plugin APIs inside your `registerEventTimelineListener` Dart function, then you need to register these plugins with the Sentiance SDK. See [this](/sdk/appendix/flutter/declaring-3rd-party-plugins.md) for more details.
{% endhint %}
{% endtab %}
{% endtabs %}
