### Observe Car Property Speed with Kotlin Source: https://github.com/paradox-cat-gmbh/karpropertymanager/blob/main/README.md This snippet demonstrates how to initialize KarPropertyManager, start observing car properties, and get a Kotlin Flow for the vehicle's speed. It requires a `Context` and a `CoroutineScope` for observation. The `VehiclePropertyIds.PERF_VEHICLE_SPEED` is used to specify the property to observe. ```kotlin val kpm = KarPropertyManager(context, scope) kpm.startObservingCar() val speedFlow = kpm.flowOfProperty(VehiclePropertyIds.PERF_VEHICLE_SPEED, 0, 0.5F) ``` -------------------------------- ### Android Activity with Jetpack Compose for KarPropertyManager Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt This Kotlin code snippet demonstrates a full Android Activity implementation using Jetpack Compose. It initializes KarPropertyManager, handles runtime permissions for car properties, and displays car status and vehicle speed. The example includes dynamic UI updates based on subscription state and permission grants, with a specified update rate for speed data. ```kotlin import android.car.Car import android.car.VehiclePropertyIds import android.content.pm.PackageManager import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts.RequestPermission import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import com.paradoxcat.karpropertymanager.KarPropertyManager import kotlinx.coroutines.flow.flowOf class MainActivity : ComponentActivity() { private var permissionsGranted by mutableStateOf(false) private val requestPermissionLauncher = registerForActivityResult(RequestPermission()) { permissionsGranted = it } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Request necessary permissions if (checkSelfPermission(Car.PERMISSION_SPEED) != PackageManager.PERMISSION_GRANTED) { requestPermissionLauncher.launch(Car.PERMISSION_SPEED) } else { permissionsGranted = true } setContent { val context = LocalContext.current val scope = rememberCoroutineScope() // Initialize KarPropertyManager val kpm = remember(context, scope) { KarPropertyManager( context = context, scope = scope ) } var subscribed by remember { mutableStateOf(false) } // Create speed flow only when subscribed and permissions granted val speedFlow = remember(subscribed, kpm, permissionsGranted) { if (permissionsGranted && subscribed) { kpm.getProperty( VehiclePropertyIds.PERF_VEHICLE_SPEED, 0, 60F // 60 Hz update rate ).valueFlow } else { flowOf() } } val speed by speedFlow.collectAsState(initial = null) val carStatus by kpm.carStatusFlow.collectAsState() Scaffold(modifier = Modifier.fillMaxSize()) { padding -> Column( modifier = Modifier .fillMaxSize() .padding(padding), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Car Status: $carStatus") if (subscribed && speed != null) { Text("Speed: ${speed?.value} m/s") Text("Timestamp: ${speed?.timestampNs}") } else if (subscribed) { Text("Waiting for speed data...") } else { Text("Not subscribed") } Spacer(modifier = Modifier.height(16.dp)) Button( onClick = { subscribed = !subscribed }, enabled = permissionsGranted ) { Text(if (subscribed) "Unsubscribe" else "Subscribe") } } } } } } ``` -------------------------------- ### Get Single Property Value Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Retrieve a one-time snapshot of a vehicle property value with timeout support. Returns null if the value cannot be retrieved within the specified timeout period. The function automatically establishes a Car service connection if needed and handles errors by throwing KarPropertyManagerException. ```APIDOC ## Get Single Property Value ### Description Retrieves a one-time snapshot of a vehicle property value with timeout support. Returns null if the value cannot be retrieved within the timeout period. Automatically establishes a Car service connection if needed and handles errors by throwing KarPropertyManagerException. ### Method `getPropertyValue(propertyId: Int, areaId: Int, timeout: Long)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **propertyId** (Int) - Required - The ID of the vehicle property to retrieve (e.g., `VehiclePropertyIds.PERF_VEHICLE_SPEED`). - **areaId** (Int) - Required - The area ID for the property. Use `0` for global properties. - **timeout** (Long) - Optional - The timeout in milliseconds for retrieving the property value. Defaults to the value set during initialization or a system default if not specified. ### Request Example ```kotlin import android.car.VehiclePropertyIds import com.paradoxcat.karpropertymanager.model.KarPropertyManagerException import kotlinx.coroutines.launch scope.launch { try { // Get vehicle speed (returns Float in m/s) val speedValue = kpm.getPropertyValue( propertyId = VehiclePropertyIds.PERF_VEHICLE_SPEED, areaId = 0, // Global property timeout = 5000L // 5 second timeout ) if (speedValue != null) { println("Current speed: ${speedValue.value} m/s") println("Timestamp: ${speedValue.timestampNs} ns") } else { println("Failed to retrieve speed (timeout)") } // Get fuel level (returns Float as percentage 0-100) val fuelLevel = kpm.getPropertyValue( propertyId = VehiclePropertyIds.FUEL_LEVEL, areaId = 0 ) // Get gear selection (returns Int) val gear = kpm.getPropertyValue( propertyId = VehiclePropertyIds.GEAR_SELECTION, areaId = 0 ) } catch (e: KarPropertyManagerException) { println("Error accessing property: ${e.cause}") // Handle permission denied, property unavailable, etc. } } ``` ### Response #### Success Response (200) - **value** (T) - The retrieved vehicle property value. The type `T` depends on the property being accessed. - **timestampNs** (Long) - The timestamp in nanoseconds when the property value was last updated. If the property cannot be retrieved within the timeout, `null` is returned. #### Response Example ```json { "value": 25.5, // Example for speed in m/s "timestampNs": 1678886400123456789 } ``` #### Error Response - **KarPropertyManagerException** - Thrown if there's an error accessing the property (e.g., permission denied, property not available, service disconnected). ``` -------------------------------- ### Get Single Vehicle Property Value in Kotlin Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Retrieves a one-time value for a specific vehicle property with an optional timeout. This function handles Car service connection establishment and cleanup. It returns a wrapper object containing the value and timestamp, or null if a timeout occurs. Exceptions are thrown for errors like permission denial. ```kotlin import android.car.VehiclePropertyIds import com.paradoxcat.karpropertymanager.model.KarPropertyManagerException import kotlinx.coroutines.launch scope.launch { try { // Get vehicle speed (returns Float in m/s) val speedValue = kpm.getPropertyValue( propertyId = VehiclePropertyIds.PERF_VEHICLE_SPEED, areaId = 0, // Global property timeout = 5000L // 5 second timeout ) if (speedValue != null) { println("Current speed: ${speedValue.value} m/s") println("Timestamp: ${speedValue.timestampNs} ns") } else { println("Failed to retrieve speed (timeout)") } // Get fuel level (returns Float as percentage 0-100) val fuelLevel = kpm.getPropertyValue( propertyId = VehiclePropertyIds.FUEL_LEVEL, areaId = 0 ) // Get gear selection (returns Int) val gear = kpm.getPropertyValue( propertyId = VehiclePropertyIds.GEAR_SELECTION, areaId = 0 ) } catch (e: KarPropertyManagerException) { println("Error accessing property: ${e.cause}") // Handle permission denied, property unavailable, etc. } } ``` -------------------------------- ### Initialize KarPropertyManager in Kotlin Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Creates an instance of KarPropertyManager, enabling automatic Car service lifecycle management. It accepts an Android Context and an optional CoroutineScope. Custom connection retention timeouts can be specified to control how long the connection remains active after the last subscription. ```kotlin import android.content.Context import com.paradoxcat.karpropertymanager.KarPropertyManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob // Basic initialization with default settings val context: Context = applicationContext val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) val kpm = KarPropertyManager(context, scope = scope) // With custom connection timeout (default is 10 seconds) val kpmWithTimeout = KarPropertyManager( context = context, carConnectionRetentionTimeoutMs = 5000L, // Keep connection alive 5 seconds after last subscription scope = scope ) ``` -------------------------------- ### KarPropertyManager Initialization Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Initialize KarPropertyManager with automatic Car service lifecycle management. You can provide an Android Context and an optional CoroutineScope. The connection is maintained as long as there are active subscriptions and closes after a timeout when subscriptions end. ```APIDOC ## Initialize KarPropertyManager ### Description Creates a KarPropertyManager instance with automatic Car service lifecycle management. Accepts an Android Context and optional CoroutineScope for managing connections. The connection is automatically maintained while active subscriptions exist and closes after a configurable timeout period when all subscriptions end. ### Method Constructor ### Parameters - **context** (Context) - Required - Android Context. - **carConnectionRetentionTimeoutMs** (Long) - Optional - Timeout in milliseconds to keep the connection alive after the last subscription ends. Defaults to 10000ms (10 seconds). - **scope** (CoroutineScope) - Optional - CoroutineScope for managing connections. Defaults to `Dispatchers.IO + SupervisorJob()`. ### Request Example ```kotlin import android.content.Context import com.paradoxcat.karpropertymanager.KarPropertyManager import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob // Basic initialization with default settings val context: Context = applicationContext val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) val kpm = KarPropertyManager(context, scope = scope) // With custom connection timeout (default is 10 seconds) val kpmWithTimeout = KarPropertyManager( context = context, carConnectionRetentionTimeoutMs = 5000L, // Keep connection alive 5 seconds after last subscription scope = scope ) ``` ``` -------------------------------- ### Configure Gradle Dependency for KarPropertyManager Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Shows how to add the KarPropertyManager library to an Android Automotive project using Gradle version catalog. It specifies the dependency and necessary Android configuration. ```gradle // libs.versions.toml [versions] karPropertyManagerVersion = "0.2.0" [libraries] karpropertymanager = { group = "com.paradoxcat", name = "karpropertymanager", version.ref = "karPropertyManagerVersion" } // app/build.gradle.kts dependencies { implementation(libs.karpropertymanager) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("androidx.core:core-ktx:1.12.0") } android { compileSdk = 35 defaultConfig { minSdk = 28 targetSdk = 35 } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = "11" } } ``` -------------------------------- ### Handle Vehicle Property Exceptions in Kotlin Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Demonstrates how to catch and handle various KarPropertyManagerExceptions, such as security access denial, property unavailability, and internal errors when retrieving vehicle properties. It also shows how to handle errors during flow subscriptions. ```kotlin import android.car.VehiclePropertyIds import android.car.hardware.property.CarInternalErrorException import android.car.hardware.property.PropertyAccessDeniedSecurityException import android.car.hardware.property.PropertyNotAvailableException import com.paradoxcat.karpropertymanager.model.KarPropertyManagerException import com.paradoxcat.karpropertymanager.model.SubscriptionUnsuccessfulException import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch scope.launch { try { // Attempt to get property value val value = kpm.getPropertyValue( propertyId = VehiclePropertyIds.PERF_VEHICLE_SPEED, areaId = 0 ) if (value == null) { // Timeout occurred println("Request timed out") } } catch (e: KarPropertyManagerException) { when (val cause = e.cause) { is PropertyAccessDeniedSecurityException -> { println("Permission denied - add to AndroidManifest.xml") // Request permission from user } is PropertyNotAvailableException -> { println("Property not available on this vehicle") // Disable feature or show message } is CarInternalErrorException -> { println("Car service internal error") // Retry or show error } is IllegalArgumentException -> { println("Invalid property ID or area ID") // Check property configuration } else -> { println("Unknown error: ${cause?.message}") } } } } // Handle subscription errors in Flow scope.launch { kpm.getProperty(VehiclePropertyIds.PERF_VEHICLE_SPEED, 0, 60F) .valueFlow .catch { e -> when (e) { is SubscriptionUnsuccessfulException -> { println("Subscription failed - may need permissions") } is KarPropertyManagerException -> { println("Property manager error: ${e.cause?.message}") } else -> { println("Unexpected error: ${e.message}") } } // Flow will complete after error } .collect { value -> println("Speed: ${value.value}") } } ``` -------------------------------- ### Kotlin: Subscribe to Vehicle Property Updates and Availability Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Subscribes to real-time vehicle property updates, such as vehicle speed, at a specified frequency. It demonstrates how to collect property value changes and monitor the availability status of the property sensor. This uses Kotlin coroutines and flows for asynchronous operations. Ensure necessary Car service permissions are granted. ```kotlin import android.car.VehiclePropertyIds import com.paradoxcat.karpropertymanager.model.PropertyAvailability import com.paradoxcat.karpropertymanager.model.SubscriptionUnsuccessfulException import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch scope.launch { // Subscribe to vehicle speed updates at 60 Hz val speedProperty = kpm.getProperty( propertyId = VehiclePropertyIds.PERF_VEHICLE_SPEED, areaId = 0, updateRateHz = 60F // Update rate in Hz ) // Collect value updates speedProperty.valueFlow .catch { e -> if (e is SubscriptionUnsuccessfulException) { println("Failed to subscribe - check permissions") } } .collect { karPropertyValue -> println("Speed: ${karPropertyValue.value} m/s at ${karPropertyValue.timestampNs}") // Update UI with speed } } scope.launch { // Monitor property availability val speedProperty = kpm.getProperty( propertyId = VehiclePropertyIds.PERF_VEHICLE_SPEED, areaId = 0, updateRateHz = 1F ) speedProperty.availabilityFlow.collect { when (it) { PropertyAvailability.AVAILABLE -> println("Speed sensor available") PropertyAvailability.UNAVAILABLE -> println("Speed sensor unavailable") PropertyAvailability.ERROR -> println("Speed sensor error") } } } ``` -------------------------------- ### Monitor Car Connection Status in Kotlin Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Observes the connection state to the Android Car service using a StateFlow. This allows for reacting to connection events like CONNECTED or DISCONNECTED, enabling UI updates or error handling. Collection can be done within a coroutine scope or directly in Jetpack Compose. ```kotlin import com.paradoxcat.karpropertymanager.model.CarStatus import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch // Collect connection status scope.launch { kpm.carStatusFlow.collect { status -> when (status) { CarStatus.CONNECTED -> { println("Car service connected") // Enable vehicle data features } CarStatus.DISCONNECTED -> { println("Car service disconnected") // Show connection error or retry } } } } // In Jetpack Compose // Assuming 'kpm' is accessible and 'collectAsState' is imported from androidx.compose.runtime // val carStatus by kpm.carStatusFlow.collectAsState() // if (carStatus == CarStatus.CONNECTED) { // Text("Connected to vehicle") // } else { // Text("Disconnected from vehicle") // } ``` -------------------------------- ### Declare AndroidManifest Permissions for Vehicle Properties Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Declare necessary permissions in AndroidManifest.xml to access specific vehicle properties. Permissions like CAR_SPEED, CAR_ENERGY, CAR_POWERTRAIN, and CAR_EXTERIOR_ENVIRONMENT are required for different data categories. For vendor-specific properties, the VENDOR_EXTENSION permission might be needed, and OEM documentation should be consulted. ```xml ``` -------------------------------- ### Declare KarPropertyManager Dependency in Gradle Source: https://github.com/paradox-cat-gmbh/karpropertymanager/blob/main/README.md This section shows how to declare the KarPropertyManager dependency in your Android project using Gradle's version catalog (`libs.versions.toml`) and `build.gradle.kts` file. It ensures the library is correctly included for use in your application. ```gradle [versions] karPropertyManagerVersion = "0.2.0" [libraries] karpropertymanager = { group = "com.paradoxcat", name = "karpropertymanager", version.ref = "karPropertyManagerVersion" } ``` ```gradle implementation(libs.karpropertymanager) ``` -------------------------------- ### Monitor Car Connection Status Source: https://context7.com/paradox-cat-gmbh/karpropertymanager/llms.txt Observe the current connection state to the Android Car service. This returns a StateFlow that emits CarStatus.CONNECTED when the service is available or CarStatus.DISCONNECTED when it is unavailable. This is useful for displaying connection status in the UI or handling service unavailability. ```APIDOC ## Monitor Car Connection Status ### Description Observes the current connection state to the Android Car service. Returns a StateFlow that emits CarStatus.CONNECTED when the service is available or CarStatus.DISCONNECTED when unavailable. Useful for displaying connection status in UI or handling service unavailability. ### Method `carStatusFlow` (getter for StateFlow) ### Parameters None ### Request Example ```kotlin import com.paradoxcat.karpropertymanager.model.CarStatus import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch // Collect connection status scope.launch { kpm.carStatusFlow.collect { status -> when (status) { CarStatus.CONNECTED -> { println("Car service connected") // Enable vehicle data features } CarStatus.DISCONNECTED -> { println("Car service disconnected") // Show connection error or retry } } } } // In Jetpack Compose val carStatus by kpm.carStatusFlow.collectAsState() if (carStatus == CarStatus.CONNECTED) { Text("Connected to vehicle") } else { Text("Disconnected from vehicle") } ``` ### Response #### Success Response - **carStatusFlow** (StateFlow) - A Flow emitting the current connection status (CONNECTED or DISCONNECTED). ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.