Android Consolidated SDK documentation - scopetech/Mobile-Public GitHub Wiki
The entry point for integrating Scope Technology's Android SDKs. Companion pages: Android Simplified SDK Integration, SmartDriveDemo Android โ App Overview. Last updated: 12 Oct 2026 for Consolidated SDK 1.1.9.
One Maven dependency, com.scopetechnology:sdk, brings every Scope SDK at versions released together, and one entry point, com.scope.sdk.ScopeSDK, drives trip recording. An app writes two small files, a host that answers whether a user is logged in and a typed configuration, and makes five calls. The SDK works out the rest: when to record, which vehicle, which permissions, and how trips reach the Portal.
| Bundled SDK | Version in 1.1.9 | Purpose |
|---|---|---|
| SmartDrive | 1.6.9 | Trip recording, detected from movement or gated on a vehicle beacon. ScopeSDK forwards to its TripWrapper facade. |
| PortalAPI Base | 1.2.9 | Login, vehicles, trips and settings from the ConnectedCar Portal. |
| BLE | 1.5.6 | Scope beacons and MHub devices. |
| Wellness | 1.1.4 | Camera-based vital sign measurement. |
| Shared classes | 1.1.7 | Models and the event bus shared by the SDKs. |
- Quick start
- Prerequisites & authentication
- Installation
- Required app configuration
- Usage in code
- Using the SDKs individually
- Updating the package
- Troubleshooting
- Framework documentation
- Integration guides
The whole integration, for an app that logs in through PortalAPI:
// app/build.gradle
implementation 'com.scopetechnology:sdk:1.1.9'// The one question the SDK asks the app.
class AppScopeHost : ScopeHost {
override fun isAuthorized(): Boolean = BasePortalApi.isLoggedIn()
}
// The values the SDK cannot guess. Everything else keeps the SDK's default.
val configuration = ScopeConfiguration(
mode = ScopeConfiguration.Mode.SMART, // or BEACON
appName = getString(R.string.app_name),
appNameAbbreviation = "APP",
notificationActivity = MainActivity::class.java,
)
// Five calls, in whatever order your app reaches them.
val host = AppScopeHost()
ScopeSDK.initialize(applicationContext, host) // Application.onCreate, in every process
ScopeSDK.start(applicationContext, configuration, host) // whenever the settings are known or change
ScopeSDK.authenticated() // after login
ScopeSDK.permissionsChanged() // once every required permission is granted
ScopeSDK.logout() // on logout
// Trip events, on the main thread.
ScopeSDK.onTripStarted = { trip -> }
ScopeSDK.onTripEnded = { trip -> }Recording arms on its own once the host reports a session, a vehicle is known, and every permission in ScopeSDK.requiredPermissions(configuration) is granted, whichever happens last. initialize restores the configuration the last start accepted, so recording resumes as soon as the process starts after a reboot or a service restart, before the app has its settings again; start with settings equal to the ones in effect changes nothing. The step-by-step version of this, with the permission flow and the callbacks, is Android Simplified SDK Integration.
The SDKs are published to GitHub Packages in a private repository. Scope Technology invites your GitHub account; contact [email protected] for access and for a test Portal account.
In GitHub, create a classic personal access token with the read:packages scope. If your organisation enforces SSO, authorise the token for the scopetech organisation after creating it.
Put the user name and token in gradle.properties, which stays out of version control:
github_username=your_github_username
github_key=your_personal_access_tokenIn the root build.gradle, alongside google() and mavenCentral():
maven {
url "https://maven.pkg.github.com/scopetech/Frameworks-Mobile"
credentials {
username = github_username
password = github_key
}
}implementation 'com.scopetechnology:sdk:1.1.9'-
compileSdk 36 or later is required since 1.1.6: the SDKs are built against API 36 and their AAR metadata says so, and a lower
compileSdkfails the build atcheckAarMetadata, naming the artifact. - minSdk 24 is the SDK's floor. The demo app uses 27 because Wellness needs it; use 27 if you include Wellness.
- targetSdk stays your choice; the demo app targets 35.
- The Wellness SDK ships native libraries that need legacy packaging:
android {
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}- The SDKs ship their own R8 keep rules. Minified release builds need no extra configuration.
After ScopeSDK.start, ScopeSDK.getDiagnostics() reports isInitialized = true and smartDriveVersion = "1.6.9". The demo app shows this as a status line reading "SmartDrive 1.6.9: ready to record", or "waiting for" followed by whatever is still missing.
The SDK tells you which runtime permissions your configuration needs on the device it is running on:
val required: List<String> = ScopeSDK.requiredPermissions(configuration)Recording is gated on the same list, so the permissions you request and the permissions the SDK waits for are always the same set.
| Permission | Required when |
|---|---|
ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION
|
Always. Android 12 requires both in one request. |
ACCESS_BACKGROUND_LOCATION |
Android 10 and later. Ask for it in its own dialog, after foreground location, as Android 11 and later require. |
ACTIVITY_RECOGNITION |
Android 10 and later, in SMART mode. Beacon-gated recording does not use it. |
POST_NOTIFICATIONS |
Android 13 and later, for the recording notification. |
READ_PHONE_STATE |
Only when phone-call distraction detection is on, or the speaker-off-after-call setting is on. |
BLUETOOTH_SCAN, BLUETOOTH_CONNECT
|
Android 12 and later, in BEACON mode. |
The SDKs declare the permissions they always need in their own manifests. Two your app declares itself, because they depend on your configuration: POST_NOTIFICATIONS, and READ_PHONE_STATE if you turn phone-call detection on. The demo app's manifest is the reference.
The app decides only the order. The demo requests location first, background location in a dialog of its own, then activity recognition, Bluetooth, phone state and notifications, requesting the next missing group each time its main screen resumes and calling ScopeSDK.permissionsChanged() once nothing is missing. Copy its PermissionsUtil.kt.
Dependable trip detection needs the app excluded from battery optimisation, which is a device setting rather than a permission. The SDK reports the state in its diagnostics and marks it in the health snapshot. Guidance per manufacturer is in the SmartDrive framework page, section 1.2.4.
The SDK posts its own notifications: the foreground recording notification, and optional distracted-driver and old-trip reminders behind typed configuration switches. Your app supplies the activity to open when the user taps them (notificationActivity) and nothing else.
The SDKs log through Timber. Plant a tree in your Application class or SDK logs go nowhere; ScopeSDK.getMissingProtocols() reports a missing tree. The demo's FileLoggingTree writes to files the user can share with support.
import com.scope.sdk.ScopeSDK
import com.scope.sdk.ScopeHost
import com.scope.sdk.ScopeConfiguration
import com.scope.mhub.tripwrapper.SmartDriveConfiguration // engine settings, when you change anyTrip recording can be integrated three ways. New apps should use the ScopeSDK facade.
| Style | What it is | Use it when |
|---|---|---|
| ScopeSDK facade โ recommended |
com.scopetechnology:sdk. One host class, one typed configuration, five calls. The facade owns ordering, gating, the vehicle, permissions and trip events. |
New integrations, and any app that also wants PortalAPI, BLE or Wellness. Least code, hardest to get wrong. |
| TripWrapper facade |
com.scopetechnology:smartdrive alone. The same calls and types as ScopeSDK, at com.scope.mhub.TripWrapper, without the other SDKs. Reference: the demo's individual_sdks branch. |
Your app needs trips only, or ships its own Portal and BLE integrations. |
Direct SCPSmartDriveManager (legacy)
|
Your app writes engine preferences, starts the recording service, registers broadcast receivers and drives sending itself. | Existing integrations only. Migrate off this with the migration guide. |
Unlike iOS, where the ScopeSDK facade is a source file copied into each app, on Android both facades ship inside the artifacts. There is nothing to copy and nothing to keep in sync.
The five lifecycle calls, where the demo makes them:
| Call | Where |
|---|---|
ScopeSDK.initialize(context, host) |
Application.onCreate, after PortalAPI is initialised, in every process. Restores the configuration the last start accepted, so recording resumes at once after a reboot or a service restart. |
ScopeSDK.start(context, configuration, host) |
Application.onCreate, right after initialize, before login and before any permission dialog; again whenever the settings change. Equal settings change nothing. |
ScopeSDK.authenticated() |
After a successful login. Safe to repeat. |
ScopeSDK.permissionsChanged() |
Once every permission in requiredPermissions is granted. |
ScopeSDK.logout() |
On logout, next to BasePortalApi.logout(). Clears the vehicle and local trips. |
Trips arrive through four main-thread callbacks, onTripStarted, onTripUpdated, onTripEnded and onTripSent; Java hosts implement TripListener; Compose screens collect tripState and tripCounts. ScopeSDK.stop() pauses recording and keeps local trips; authenticated() arms it again. An app without PortalAPI passes the vehicle it selects, with its unit type, to ScopeSDK.vehicleSelected(unitSerialNumber, unitType); an app on PortalAPI writes no vehicle code.
- PortalAPI Base handles login and selects the vehicle. It announces the selected vehicle to the SDK on the shared event bus, so the app relays nothing. Framework page.
-
BLE is needed in
BEACONmode: configure the beacon manager, start the scanner service after permissions, pair a beacon to the vehicle. Framework page. - Wellness fetches its licence key from the Portal's mobile settings and needs the camera permission. Framework page.
An app that needs only some of the SDKs depends on them directly, at the versions the consolidated SDK bundles:
implementation 'com.scopetechnology:shared-classes:1.1.7'
implementation 'com.scopetechnology:smartdrive:1.6.9'
implementation 'com.scopetechnology:portal-api-base:1.2.9'
implementation 'com.scopetechnology:ble:1.5.6'
implementation 'com.scopetechnology:wellness:1.1.4'With SmartDrive alone, integrate at com.scope.mhub.TripWrapper; see Android TripWrapper SDK. The demo's individual_sdks branch is this setup in working form. Do not mix the consolidated artifact with individual ones.
Bump the one version and rebuild. Confirm what resolved with ./gradlew :app:dependencies --configuration debugRuntimeClasspath.
| Consolidated SDK | Date | SmartDrive | PortalAPI Base | BLE | Wellness | Shared classes |
|---|---|---|---|---|---|---|
| 1.1.9 | 12 Oct 2026 | 1.6.9 | 1.2.9 | 1.5.6 | 1.1.4 | 1.1.7 |
1.1.9 is the 1.1 line in its final form; 1.1.5 to 1.1.8 were interim builds and are superseded by it. The 1.1 line is the first with ScopeSDK (1.0.x bundled the same SDKs without an entry point) and the first that requires compileSdk 36 (section 3.2). From an interim 1.1 build: bump the version, and add ScopeSDK.initialize to Application.onCreate before start if you do not call it yet; the old sequence keeps working without the restore.
What each SmartDrive version changed is in the SmartDrive release notes.
Authentication and resolution
-
Could not resolve com.scopetechnology:sdk, or a 401: the token lacksread:packages, is not SSO-authorised, or the repository block is missing from the rootbuild.gradle. Property names aregithub_usernameandgithub_key. - Duplicate class errors: the consolidated artifact and an individual SDK are both on the classpath. Use one or the other.
Build errors
-
checkAarMetadatafails because acom.scopetechnologydependency "requires libraries and applications that depend on it to compile against version 36 or later": raisecompileSdkto 36, section 3.2. - Native library errors around Wellness: add the
useLegacyPackagingblock from section 3.2.
Runtime
- The status line says "waiting for":
ScopeSDK.getDiagnostics().missingProtocolsandmissingPermissionsname exactly what is missing. The common ones are no session yet, no vehicle announced yet, no Timber tree, and background location not granted. - No SDK log lines at all: no Timber tree is planted.
- A trip failed to upload and never retried:
resendFailedTripsis off by default. Turn it on, or offer a button that callsScopeSDK.retryFailedTrips(), which sends failed and quarantined trips whatever the setting says (SmartDrive 1.6.9). - A short test trip vanished: trips under 102 metres are discarded at trip end. Walk or drive further.
- Trips stop on some phones after a while: battery optimisation, section 4.3. The health snapshot marks it with a warning.
- SmartDrive โ Android SmartDrive framework (direct manager API) ยท Release notes
- TripWrapper โ SDK reference ยท Migration guide
- PortalAPI Base โ Android PortalApiBase framework
- BLE โ Android SBeacon framework
- Wellness โ Android Wellness framework
Simplified integration โ the recommended path, step by step:
Demo app โ a complete worked integration, smart and beacon, with a per-component reference:
Session & app lifecycle โ keep users logged in and recording across screen-off, background and process death:
Diagnostics โ what the SDK can tell you and support about an integration:
Support โ [email protected]