This file is the authoritative context document for any AI agent working in this repository. Read it before making changes.
oacp-android is the official Kotlin SDK for the Open App Capability Protocol. It provides base classes that handle all OACP plumbing — ContentProvider registration, intent handling, parameter extraction, result broadcasting — so app developers only write their business logic.
Maven coordinates: org.oacp:oacp-android:0.3.0
Min SDK: 21 | Compile SDK: 35 | Kotlin: 2.0.21 | Java: 17
oacp-android-sdk/
├── build.gradle.kts # Root build config (AGP 8.5.2, Kotlin 2.0.21)
├── settings.gradle.kts # Includes :oacp-android module
├── gradle.properties
├── gradlew + gradle/ # Gradle wrapper
├── oacp-android/ # SDK library module
│ ├── build.gradle.kts # Library config (namespace: org.oacp.android)
│ └── src/
│ ├── main/
│ │ ├── kotlin/org/oacp/android/
│ │ │ ├── Oacp.kt # Protocol constants (actions, extras, statuses, errors)
│ │ │ ├── OacpReceiver.kt # Abstract BroadcastReceiver with goAsync() threading
│ │ │ ├── OacpActivity.kt # Abstract Activity for foreground actions
│ │ │ ├── OacpProvider.kt # ContentProvider serving oacp.json + OACP.md
│ │ │ ├── OacpParams.kt # Type-safe parameter accessor with suffix resolution
│ │ │ ├── OacpResult.kt # Result builder + broadcaster
│ │ │ └── OacpEntitySource.kt # Interface for dynamic entity data
│ │ └── AndroidManifest.xml # Auto-registers OacpProvider via manifest merger
│ └── test/
│ └── kotlin/org/oacp/android/
│ ├── OacpTest.kt
│ ├── OacpReceiverTest.kt
│ ├── OacpActivityTest.kt
│ ├── OacpProviderTest.kt
│ ├── OacpParamsTest.kt
│ ├── OacpResultTest.kt
│ └── OacpEntityTest.kt
├── README.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
└── LICENSE # Apache 2.0
ACTION_RESULT = "org.oacp.ACTION_RESULT"— broadcast action for async resultsEXTRA_REQUEST_ID,EXTRA_STATUS,EXTRA_CAPABILITY_ID,EXTRA_MESSAGE,EXTRA_RESULT,EXTRA_ERROR_CODE- Status values:
STATUS_ACCEPTED,STATUS_STARTED,STATUS_COMPLETED,STATUS_FAILED,STATUS_CANCELLED - Error codes:
ERROR_INVALID_PARAMETERS,ERROR_NOT_FOUND,ERROR_NOT_AUTHENTICATED,ERROR_INTERNAL, etc. - Provider:
PROVIDER_AUTHORITY_SUFFIX = ".oacp", paths:/manifest,/context,/entities
Abstract BroadcastReceiver. Uses goAsync() + thread pool internally (no ANR risk).
abstract fun onAction(context: Context, action: String, params: OacpParams, requestId: String?): OacpResult?Abstract Activity. Auto-extracts requestId, capabilityId, params from intent.
protected abstract fun onOacpAction(action: String, params: OacpParams)
protected fun sendResult(result: OacpResult, targetPackage: String? = null)ContentProvider auto-registered via manifest merger at ${applicationId}.oacp.
/manifest→ servesassets/oacp.jsonwith__APPLICATION_ID__substitution/context→ servesassets/OACP.md/entities/<type>?q=query→ dynamic entity data viaOacpEntitySource
Type-safe accessor with suffix-based key resolution for build variant safety.
params.getString("query") // finds "query", "EXTRA_QUERY", ".EXTRA_QUERY", etc.
params.getInt("amount") // handles int/long/string/double coercion
params.getBoolean("enabled") // handles bool/string/int coercionOacpResult.success("Battery is at 85%")
OacpResult.error(Oacp.ERROR_NOT_FOUND, "No alarms set")
OacpResult.cancelled("User cancelled")interface OacpEntitySource {
fun queryEntities(context: Context, entityType: String, query: String?): List<OacpEntity>
}./gradlew :oacp-android:build # Build
./gradlew :oacp-android:test # Run tests (Robolectric)
./gradlew :oacp-android:lint # LintRobolectric + JUnit 4. Tests use CountDownLatch for async verification of goAsync() completion.
- Explicit API mode is ON. Every public symbol needs explicit
publicvisibility. Internal helpers must beinternalorprivate. - Backward compatibility matters. This is a library consumed by third-party apps. Do not break public method signatures without version bump.
__APPLICATION_ID__substitution in OacpProvider is critical for build variant support (debug/release). Do not change this behavior.- Suffix-based key resolution in OacpParams is intentional — it handles the case where intent extras are prefixed with the app's package name. Do not simplify to exact-match only.
- Feature branches only. Never commit directly to
main. - Stage specific files. Never
git add -A.
| Repo | What |
|---|---|
| OpenAppCapabilityProtocol/oacp | Protocol spec, docs, example app |
| OpenAppCapabilityProtocol/hark | Reference voice assistant that consumes OACP |
- Remote:
https://github.com/OpenAppCapabilityProtocol/oacp-android-sdk.git - Default branch:
main