How voice control was added to BinaryEye using the OACP Kotlin SDK.
Three capabilities, all activity-only (every action opens the app):
| Capability | Target Activity | What it does |
|---|---|---|
scan_barcode |
CameraActivity | Opens camera viewfinder to scan |
scan_from_image |
PickActivity | Opens image picker to scan from photo |
create_barcode |
CameraActivity | Opens barcode creator |
This is the activity-only pattern — the simplest integration. No OacpReceiver needed because every action requires the app UI.
- All capabilities use
"type": "activity"in oacp.json - Intent filters are on the actual target Activities (not a generic MainActivity)
- Hark calls
startActivity()directly from the foreground
| File | Purpose |
|---|---|
app/libs/oacp-android-release.aar |
OACP Kotlin SDK (for OacpProvider auto-registration) |
app/src/main/assets/oacp.json |
Capability manifest |
app/src/main/assets/OACP.md |
LLM context for disambiguation |
implementation files('libs/oacp-android-release.aar')
implementation "androidx.annotation:annotation:1.7.1"Intent filters on the actual target activities:
<!-- On CameraActivity -->
<intent-filter>
<action android:name="${applicationId}.oacp.ACTION_SCAN_BARCODE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="${applicationId}.oacp.ACTION_CREATE_BARCODE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<!-- On PickActivity -->
<intent-filter>
<action android:name="${applicationId}.oacp.ACTION_SCAN_FROM_IMAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>Intent filters are placed on the specific target Activity rather than a generic entry point. This means:
scan_barcode→ opens directly in CameraActivity (camera viewfinder)scan_from_image→ opens directly in PickActivity (image picker)- No intermediate routing needed
CameraActivity reads the OACP intent and routes to the correct screen:
// In CameraActivity.onCreate(), after existing intent handling:
if (intent?.action?.endsWith(".oacp.ACTION_CREATE_BARCODE") == true) {
val content = intent.getStringExtra("content")
if (!content.isNullOrEmpty()) {
startActivity(EncodeActivity.newIntent(this, content))
finish()
return
}
}This demonstrates the key principle: the SDK handles discovery and dispatch, but the app handles routing to the correct screen and reading parameters.
- Return scan results via
OacpResult(would need adding a broadcast receiver for result reporting)
# Verify manifest
adb shell content read --uri "content://de.markusfisch.android.binaryeye.debug.oacp/manifest"
# Open scanner
adb shell am start -a de.markusfisch.android.binaryeye.debug.oacp.ACTION_SCAN_BARCODE \
-n de.markusfisch.android.binaryeye.debug/de.markusfisch.android.binaryeye.activity.CameraActivity
# Open image scanner
adb shell am start -a de.markusfisch.android.binaryeye.debug.oacp.ACTION_SCAN_FROM_IMAGE \
-n de.markusfisch.android.binaryeye.debug/de.markusfisch.android.binaryeye.activity.PickActivity