sample-app-guide

Building a complete DAT app with session creation, camera streaming, and photo capture

npx skills add https://github.com/facebook/meta-wearables-dat-android --skill sample-app-guide

Sample App Guide (Android)

Build an Android DAT app with registration, sessions, camera streaming, and photo capture.

Pair this with the CameraAccess sample.

Project setup

  1. Create an Android Studio app project.
  2. Add the DAT Maven repository and dependencies.
  3. Configure AndroidManifest.xml for registration callbacks plus APPLICATION_ID and CLIENT_TOKEN.
  4. Initialize Wearables in your Application.

Suggested app structure

app/src/main/java/com/example/myapp/
├── MyApplication.kt
├── MainActivity.kt
├── session/
│   └── SessionViewModel.kt
└── ui/
    ├── RegistrationScreen.kt
    └── CameraScreen.kt

Registration and session creation

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            Wearables.registrationState.collect { state ->
                // Update registration UI
            }
        }
    }

    fun register() {
        Wearables.startRegistration(this)
    }
}

DeviceSession.start() is fire-and-forget. Attach the camera from the session-state collector once the session reports DeviceSessionState.STARTED; adding a capability to an IDLE session fails with DeviceSessionError.SESSION_IDLE.

class SessionViewModel : ViewModel() {
    private var session: DeviceSession? = null
    private var camera: Camera? = null

    fun startCameraSession() {
        Wearables.createSession(AutoDeviceSelector()).fold(
            onSuccess = { createdSession ->
                session = createdSession

                viewModelScope.launch {
                    createdSession.errors.collect { error -> showError(error.description) }
                }
                viewModelScope.launch {
                    createdSession.state.collect { state ->
                        when (state) {
                            DeviceSessionState.STARTED -> attachCamera(createdSession)
                            DeviceSessionState.STOPPED -> clearSession(createdSession)
                            else -> Unit
                        }
                    }
                }

                createdSession.start()
            },
            onFailure = { error, _ -> showError(error.description) },
        )
    }

    private fun attachCamera(activeSession: DeviceSession) {
        if (camera != null) return
        activeSession.addCamera(
            StreamConfiguration(videoQuality = VideoQuality.MEDIUM, frameRate = 24),
        ).fold(
            onSuccess = { addedCamera ->
                camera = addedCamera
                addedCamera.stream.start().onFailure { error, _ ->
                    showError(error.description)
                }
            },
            onFailure = { error, _ -> showError(error.description) },
        )
    }

    private fun clearSession(stoppedSession: DeviceSession) {
        if (session !== stoppedSession) return
        camera = null
        session = null
    }
}

Observe frames and capture photos

viewModelScope.launch {
    camera?.stream?.videoStream?.collect { frame ->
        // Render preview
    }
}

fun capturePhoto() {
    viewModelScope.launch {
        camera?.stream?.capturePhoto()
            ?.onSuccess { photoData ->
                when (photoData) {
                    is PhotoData.Bitmap -> savePhoto(photoData.bitmap)
                    is PhotoData.HEIC -> saveHeic(photoData.data)
                }
            }
            ?.onFailure { error, _ ->
                showCaptureError(error.description)
            }
    }
}

Shutdown

fun stopCameraSession() {
    camera?.stop()
    session?.stop()
    camera = null
    session = null
}

Testing with MockDeviceKit

Use MockDeviceKit to simulate linking glasses, permission state, and camera media without physical hardware. See MockDevice Testing for setup details.

Links

More skills from facebook

gc-safe-coding
facebook
For the full explanation and rationale, see doc/GCSafeCoding.md .
app-review-prep
facebook
Prepare a Meta app for App Review — checks current status, outstanding requirements, granted privileges, and submission history. Use before submitting an app…
api-health
facebook
Monitor API health for a Meta app — check rate limits, call volume, and API deprecations. Use to diagnose throttling, plan capacity, or prepare for API version…
debug-webhooks
facebook
Troubleshoot webhook issues for a Meta app — inspect active subscriptions, identify misconfiguration, and send test payloads to verify delivery. Use when…
api-integration
facebook
Guide a developer through setting up a Meta API integration from scratch — discovers the right APIs, fetches setup guides, authentication requirements,…
webhook-setup
facebook
Set up webhooks for a Meta app end-to-end — discover available topics, subscribe to fields, and verify with a test payload. Use when configuring webhooks for…
test-ui
facebook
Test UI system (PanelUI, ScreenSpace) against the poke example using the iwsdk CLI.
flags
facebook
Inspect and compare feature flag states across React release channels. View all flags across channels (www, www-modern, canary, next, experimental, rn variants) or compare specific channels with --diff Output formats include default table view, CSV export, and cleanup status grouping Flag states indicated by symbols: enabled (✅), disabled (❌), variant testing (🧪), profiling-only (📊) Common pitfall: __VARIANT__ flags are tested in both states on www; use --diff to spot meaningful...