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
CUSTOMAPPand correctpackageName. IGlassAppCbkregistered.
Core APIs
| Method | Description |
|---|---|
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
| Callback | Description |
|---|---|
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:
context.getExternalFilesDir(“DCIM/Rokid”)/cxrL.apk— recommended, usually no extra storage permissioncontext.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
| Item | Phone CXR-L | Glasses CXR-S |
|---|---|---|
| Target package | CUSTOMAPP.packageName | applicationId |
| Launch entry | appStart(”${packageName}${activityClass}”) | Matching Activity in Manifest |
| Sample default | com.rokid.cxrswithcxrl + .activities.main.MainActivity | Same |
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
- Phone Hub calls
appIsInstalled/appUploadAndInstallif needed. - After link ready, call
appStartwithIGlassAppCbk. onOpenAppResult(true)means the glasses Activity is up — session build complete.- Then audio, photo, custom commands.
Glasses MainActivity.onCreate creates MainViewModel; its init registers CXRServiceBridge subscribe.
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
packageNameand 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.