CXR-L(EN)
cxr-l-sdk · v1.0.3 · snapshot 2026-06-02· ↗ source

Glasses Custom APP

Android: Glasses Custom App

Overview

In a CUSTOMAPP session, specify the glasses-side target package and use the SDK to query installation, upload & install APK, start Activity, stop, and uninstall on the glasses. After the target app is running and interactive on the glasses, CustomApp scene building is complete and audio, photo, and custom commands become available.

Prerequisites

  • Connection and Session configured with CUSTOMAPP and correct packageName.
  • IGlassAppCbk registered.

Core APIs

MethodDescription
appIsInstalled(IGlassAppCbk)Query whether target package is installed
appUploadAndInstall(apkAbsolutePath, IGlassAppCbk)Upload local APK and install
appStart(entryUriOrComponent, IGlassAppCbk)Start app; use ”${packageName}${activityClassName}”
appStop(IGlassAppCbk)Stop app
appUninstall(IGlassAppCbk)Uninstall app

IGlassAppCbk callbacks

CallbackDescription
onQueryAppResult(installed: Boolean)Installation query result
onInstallAppResult(success: Boolean)Install result
onOpenAppResult(success: Boolean)Launch result; true means scene building success
onStopAppResult(success: Boolean)Stop result
onUnInstallAppResult(success: Boolean)Uninstall result
onGlassAppResume(resumed: Boolean)Foreground/background transition on glasses

Integration steps

link.appIsInstalled(appCallback)
val apkPath = context.getExternalFilesDir(“DCIM/Rokid”)!!.resolve(“cxrL.apk”).absolutePath
link.appUploadAndInstall(apkPath, appCallback)
val entry = ”${targetPackage}.activities.main.MainActivity”
link.appStart(entry, appCallback)
link.appStop(appCallback)
link.appUninstall(appCallback)

APK path and storage permissions

Prefer app-specific directories:

  1. context.getExternalFilesDir(“DCIM/Rokid”)/cxrL.apkrecommended, usually no extra storage permission
  2. context.filesDir/cxrL.apk

For public paths (e.g. /sdcard/DCIM/Rokid/cxrL.apk), grant storage permissions per the SDK Integration chapter and verify canRead() before appUploadAndInstall. Sample uses ApkInstallAccess and CxrSessionActivity permission flows.

Wrap appUploadAndInstall in runCatching for I/O errors.

Glasses-side integration (CXR-S)

The CUSTOMAPP target app runs on glasses and must be built with CXR-S SDK (cxr-service-bridge), paired with phone CXR-L. Glasses apps do not authenticate on their own; CXR-L remotely installs and starts them, then exchanges Caps on the same link.

SDK integration: glasses-side (CXR-S) section. Custom commands: Custom Commands chapter.

CUSTOMAPP alignment

ItemPhone CXR-LGlasses CXR-S
Target packageCUSTOMAPP.packageNameapplicationId
Launch entryappStart(”${packageName}${activityClass}”)Matching Activity in Manifest
Sample defaultcom.rokid.cxrswithcxrl + .activities.main.MainActivitySame

RenewCXRLSample constants:

val APP_PACKAGE_NAME = “com.rokid.cxrswithcxrl”
val MAIN_PAGE =.activities.main.MainActivity”
// appStart: ”${APP_PACKAGE_NAME}${MAIN_PAGE}”

Launch and session build

  1. Phone Hub calls appIsInstalled / appUploadAndInstall if needed.
  2. After link ready, call appStart with IGlassAppCbk.
  3. onOpenAppResult(true) means the glasses Activity is up — session build complete.
  4. Then audio, photo, custom commands.

Glasses MainActivity.onCreate creates MainViewModel; its init registers CXRServiceBridge subscribe.

Rendering diagram…

Bridge initialization

class MainViewModel : ViewModel() {
private val cxrBridge = CXRServiceBridge()
init {
cxrBridge.setStatusListener(connectionCallback)
cxrBridge.subscribe(“rk_custom_client”, msgCallback)
}
}

Constraints

  • App is started remotely; do not assume launcher-only entry (Sample keeps launcher filter for standalone debug).
  • After APK upgrade, rerun install/start so subscribe runs in the new process.
  • Mismatched SDK versions may break link or Caps parsing — keep Samples on paired versions.

Constraints

  • packageName and entry Activity must match the glasses APK Manifest.
  • Large APK installs may be slow over Bluetooth; implement retries at the app layer.
  • Custom commands must reuse the same session CXRLink — see Custom Commands chapter.
  • Call audio/photo/commands only after scene building completes.

Next steps

  • Audio / Photo Capture — available after CustomApp scene building
  • Custom Commands — CustomApp sessions only
  • Keys and System Broadcasts — key reporting

Appendix: reference sample

RenewCXRLSample default target com.rokid.cxrswithcxrl, entry .activities.main.MainActivity.

Marcin Miazga