Skip to main content

Overview

The Synheart Behavior Dart/Flutter SDK provides real-time behavioral signal inference from digital interactions for cross-platform mobile applications.

Installation

Add to pubspec.yaml:
dependencies:
  synheart_behavior: ^0.1.4
Install:
flutter pub get

Requirements

  • Flutter >= 3.10.0
  • Dart >= 3.0.0

Quick Start

Basic Usage

import 'package:synheart_behavior/synheart_behavior.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize SDK
  final behavior = await SynheartBehavior.initialize(
    config: const BehaviorConfig(
      enableInputSignals: true,
      enableAttentionSignals: true,
      enableMotionLite: true, // Enable motion state inference (LAYING, MOVING, SITTING, STANDING)
    ),
  );

  runApp(MyApp(behavior: behavior));
}

class MyApp extends StatelessWidget {
  final SynheartBehavior behavior;

  const MyApp({super.key, required this.behavior});

  @override
  Widget build(BuildContext context) {
    return behavior.wrapWithGestureDetector(
      MaterialApp(
        title: 'My App',
        home: HomePage(behavior: behavior),
      ),
    );
  }
}

Real-Time Event Tracking

// Listen to real-time events
behavior.onEvent.listen((event) {
  print('Event: ${event.eventType} at ${event.timestamp}');
  print('Metrics: ${event.metrics}');

  // Handle different event types
  switch (event.eventType) {
    case BehaviorEventType.scroll:
      final velocity = event.metrics['velocity'] as double?;
      print('Scroll velocity: $velocity px/s');
      break;
    case BehaviorEventType.tap:
      final duration = event.metrics['tap_duration_ms'] as int?;
      print('Tap duration: $duration ms');
      break;
    case BehaviorEventType.swipe:
      final direction = event.metrics['direction'] as String?;
      print('Swipe direction: $direction');
      break;
    case BehaviorEventType.typing:
      final speed = event.metrics['typing_speed'] as double?;
      final tapCount = event.metrics['typing_tap_count'] as int?;
      print('Typing speed: $speed, tap count: $tapCount');
      break;
    default:
      break;
  }
});

Session Management

// Start a session
final session = await behavior.startSession();
print('Session started: ${session.sessionId}');

// ... user interacts with app ...

// End session and get summary
final summary = await session.end();
print('Session duration: ${summary.durationMs}ms');
print('Total events: ${summary.activitySummary.totalEvents}');
print('Focus hint: ${summary.behavioralMetrics.focusHint}');
print('Distraction score: ${summary.behavioralMetrics.distractionScore}');

On-Demand Metrics Calculation

Calculate behavioral metrics for a custom time range within a session:
// Calculate metrics for a specific time range
final metrics = await behavior.calculateMetricsForTimeRange(
  startTimestampSeconds: 1767688063,  // Unix timestamp in seconds
  endTimestampSeconds: 1767688130,     // Unix timestamp in seconds
  sessionId: 'SESS-1767688063415',     // Optional: uses current session if not provided
);

// Access the calculated metrics
print('Total events: ${metrics['activity_summary']['total_events']}');
print('App switches: ${metrics['activity_summary']['app_switch_count']}');
print('Interaction intensity: ${metrics['behavioral_metrics']['interaction_intensity']}');
print('Distraction score: ${metrics['behavioral_metrics']['behavioral_distraction_score']}');
print('Focus hint: ${metrics['behavioral_metrics']['focus_hint']}');

// Motion state (if motion data is available)
if (metrics['motion_state'] != null) {
  print('Motion state: ${metrics['motion_state']['major_state']}');
  print('Confidence: ${metrics['motion_state']['confidence']}');
}

// Device context
print('Screen brightness: ${metrics['device_context']['avg_screen_brightness']}');
print('Orientation: ${metrics['device_context']['start_orientation']}');

// System state
print('Internet: ${metrics['system_state']['internet_state']}');
print('Do not disturb: ${metrics['system_state']['do_not_disturb']}');
Note: The time range must be within the session’s start and end times. The SDK automatically validates this and will throw an error if the range is out of bounds.

API Reference

SynheartBehavior

Main Methods:
MethodDescriptionReturns
initialize({config})Initialize SDKFuture<SynheartBehavior>
wrapWithGestureDetector(widget)Wrap app to enable gesture trackingWidget
startSession({sessionId})Start a new sessionFuture<BehaviorSession>
calculateMetricsForTimeRange(...)Calculate metrics for custom time rangeFuture<Map<String, dynamic>>
getCurrentStats()Get current statisticsFuture<BehaviorStats>
onEventStream of behavioral eventsStream<BehaviorEvent>
dispose()Clean up resourcesvoid

calculateMetricsForTimeRange()

Calculate behavioral metrics for a custom time range within a session. Parameters:
ParameterTypeRequiredDescription
startTimestampSecondsintYesStart time as Unix timestamp in seconds
endTimestampSecondsintYesEnd time as Unix timestamp in seconds
sessionIdString?NoSession ID (uses current session if not provided)
Returns: Future<Map<String, dynamic>> - Map containing all behavioral metrics for the specified time range Throws: Exception if time range is out of session bounds or session not found Example:
final metrics = await behavior.calculateMetricsForTimeRange(
  startTimestampSeconds: DateTime.now().subtract(Duration(minutes: 5)).millisecondsSinceEpoch ~/ 1000,
  endTimestampSeconds: DateTime.now().millisecondsSinceEpoch ~/ 1000,
);

// Access metrics
final totalEvents = metrics['activity_summary']['total_events'] as int;
final intensity = metrics['behavioral_metrics']['interaction_intensity'] as double;
Properties:
PropertyTypeDescription
isInitializedboolWhether SDK is initialized
currentSessionIdString?Current active session ID

BehaviorConfig

Parameters:
ParameterTypeDefaultDescription
enableInputSignalsbooltrueEnable scroll, tap, swipe, typing tracking
enableAttentionSignalsbooltrueEnable app switching, idle gaps
enableMotionLiteboolfalseEnable motion state inference
sessionIdPrefixString'SESS'Prefix for session IDs
userIdString?nullOptional user identifier
deviceIdString?nullOptional device identifier
eventBatchSizeint10Events per batch
maxIdleGapSecondsdouble10.0Max idle time before task drop

BehaviorEvent

Properties:
PropertyTypeDescription
eventIdStringUnique event identifier
sessionIdStringAssociated session ID
timestampDateTimeEvent timestamp
eventTypeBehaviorEventTypeType of event
metricsMap<String, dynamic>Event-specific metrics
Event Types:
  • BehaviorEventType.scroll - Scroll interactions
  • BehaviorEventType.tap - Tap interactions
  • BehaviorEventType.swipe - Swipe interactions
  • BehaviorEventType.typing - Typing session events
  • BehaviorEventType.notification - Notification events
  • BehaviorEventType.call - Call events

BehaviorSession

Methods:
MethodDescriptionReturns
end()End session and get summaryFuture<BehaviorSessionSummary>
Properties:
PropertyTypeDescription
sessionIdStringSession identifier

BehaviorSessionSummary

Properties:
PropertyTypeDescription
sessionIdStringSession identifier
startAtDateTimeSession start time
endAtDateTimeSession end time
durationMsintSession duration in milliseconds
behavioralMetricsBehavioralMetricsBehavioral metrics
activitySummaryActivitySummaryActivity summary
notificationSummaryNotificationSummaryNotification summary
motionStateMotionState?Motion state (if enabled)

BehavioralMetrics

Properties:
PropertyTypeDescription
interactionIntensitydoubleOverall interaction rate (0-1)
distractionScoredoubleDistraction proxy (0-1)
focusHintdoubleFocus quality proxy (0-1)
deepFocusBlocksList<DeepFocusBlock>Sustained focus periods
taskSwitchRatedoubleApp switching frequency
idleRatiodoubleProportion of idle time
fragmentedIdleRatiodoubleFragmented vs continuous idle
burstinessdoubleTemporal clustering of events
notificationLoaddoubleNotification pressure
scrollJitterRatedoubleScroll pattern irregularity
typingSpeeddoubleAverage typing speed (taps per second)
typingCadenceStabilitydoubleConsistency of typing rhythm (0-1)
typingCadenceVariabilitydoubleVariability in timing between taps
typingActivityRatiodoubleFraction of session with active typing (0-1)
typingGapRatiodoubleProportion of intervals that are gaps (0-1)
typingBurstinessdoubleTemporal clustering of typing events
typingInteractionIntensitydoubleOverall typing engagement (0-1)

Permissions

Notification Permission

// Check if permission is granted
final hasPermission = await behavior.checkNotificationPermission();

if (!hasPermission) {
  // Request permission
  final granted = await behavior.requestNotificationPermission();
  if (granted) {
    print('Notification permission granted');
  }
}

Call Permission

// Check if permission is granted
final hasPermission = await behavior.checkCallPermission();

if (!hasPermission) {
  // Request permission
  await behavior.requestCallPermission();
}

Configuration

Update Configuration at Runtime

 await behavior.updateConfig(const BehaviorConfig(
  enableInputSignals: true,
  enableAttentionSignals: true,
  enableMotionLite: true,  
));

Resources

For comprehensive documentation, see the full README on GitHub.
Author: Yoseph Gebeyehu