Startup and recovery
After privacy consent and a platform session are available, call recover to reconcile saved pending results, then list for the cloud vehicle list. cached is for display only, not proof of current authorization or binding. Handle recovery failures by their error type; do not delete records to bypass a failure.
Android supports typed methods or execute(action, parametersJson, callback). iOS uses execute:parameters:resolve:reject:. Both platforms share these cloud action names and object parameters:
| Action | Parameters and purpose |
|---|---|
recover, list, cached |
Empty object; recovery, cloud list or cached list |
add |
Empty object; enter the add-vehicle flow |
bootstrap |
discoveryId, optional expectedTerminal; obtain bootstrap authorization |
bind |
terminalId; submit binding proof and restore target connection authorization |
select, report |
vehicleId, deviceId, terminalId; select or report a connected terminal |
restoreSelection |
terminalId; restore the prior selection after cancelling discovery |
clearBootstrap |
Empty object; clear temporary bootstrap authorization |
release |
terminalId; revoke nearby terminal authorization |
unbind |
vehicle: the complete entry from list, including vehicle.bindingVersion and terminals |
authorizePairingRecovery |
terminalId, nonce; return proof for continuing PIN recovery through the device client |
adoptLegacy |
Empty object; claim only after verifying the legacy origin; see upgrade guidance |
First connection
- Save the existing selection, call
addand begin device scanning. - Read
discoveryIdfrom discovery and callbootstrap. IncludeexpectedTerminalwhen the target is known. - Use the device pairing API for the secure handshake, then submit the PIN shown on the actual terminal.
- After pairing, call
bind. Refresh the vehicle list and target state after cloud binding completes. - Prepare and connect vehicle Wi-Fi as needed. Verify authentication and connection probes for the expected
terminalId. - Clear bootstrap authorization after success, failure or cancellation. Retain SDK-managed pending receipts for
recover.
A Bluetooth connection, successful system pairing, matching SSID or Wi-Fi join callback alone does not prove an authenticated vehicle connection. Do not prematurely display successful binding or vehicle control.
Selection, cancellation and unbinding
Use select for an authorized vehicle. When cancelling an add flow, stop discovery and temporary pairing, wait for old operations to settle, then call restoreSelection for the previous vehicle. Check the active operation and target on every asynchronous callback so a late result from the previous vehicle cannot overwrite the current state.
Call cancel() and wait for resolve/reject. Cancellation does not roll back facts already confirmed by the terminal or server. Do not switch or remove vehicles during navigation. On NAVIGATION_ACTIVE, ask the user to end navigation first.
release revokes nearby terminal authorization; unbind performs cloud unbinding with a binding version. If the unbind result is unknown, retry with the same bindingVersion. Recovery resumes pending work after the original account signs in. Do not manually clear pendingReceipt, pendingChallenge or pendingUnbind.
Commands and state
Show controls according to actual terminal capabilities and user authorization. Send a vehicle command once for each explicit user action and wait for its receipt. Never automatically replay it on reconnect, UI recreation or timeout.
State reads and command receipts are different results. Show execution success based on the corresponding receipt and valid subsequent state, not stale cached state. Ongoing navigation, media and background connectivity also depend on host extensions, permissions and terminal support.
Concurrency
The SDK maintains one device business session. When mutually exclusive actions such as binding, selection or unbinding return CLOUD_BUSY, wait for the active operation to settle before refreshing. Android 0.2.1 coalesces same-scope list and recovery requests. Each caller cancels only its own result, without affecting other subscribers. If all callers cancel, shared work may still finish or time out so confirmed receipts remain recoverable. During another exclusive operation, recover returns CLOUD_BUSY; retry after it settles. Recreate clients after account or token changes.
Android: recover, then read
Use each coordinator once, creating, starting and cancelling it on the main thread after SDK configuration and session installation. The host’s isCurrent checks the account, vehicle and UI operation generation. Invalidate it before cancel() when leaving the page or changing session. Retain the coordinator until settlement.
Success reaches result.resolve; failure reaches result.reject for error handling. Cancellation withdraws this subscriber’s result; shared SDK recovery already in progress may still finish.
import net.oou.mobile.CloudOperation
import net.oou.mobile.CloudVehicles
import net.oou.mobile.ResultCallback
class VehicleRefresh(
private val vehicles: CloudVehicles,
private val isCurrent: () -> Boolean,
private val result: ResultCallback
) {
private var recovery: CloudOperation? = null
private var listing: CloudOperation? = null
private var started = false
private var cancelled = false
private fun current() = !cancelled && isCurrent()
private val listResult = object : ResultCallback {
override fun resolve(value: Any?) {
if (current()) result.resolve(value)
}
override fun reject(code: String, message: String?, cause: Throwable?) {
if (current()) result.reject(code, message, cause)
}
}
fun start() {
check(!started)
started = true
if (!current()) return
recovery = vehicles.recover(object : ResultCallback {
override fun resolve(value: Any?) {
if (current()) listing = vehicles.list(listResult)
}
override fun reject(code: String, message: String?, cause: Throwable?) {
listResult.reject(code, message, cause)
}
})
}
fun cancel() {
cancelled = true
recovery?.cancel()
listing?.cancel()
}
}
