Glasses Custom View
Android: Glasses Custom View
Overview
In a CUSTOMVIEW session, deliver layout JSON and icon resources (Base64 PNG) from the phone to the glasses, render the UI on the glasses, and support open / incremental update / close. After onCustomViewOpened, CustomView scene building is complete and audio/photo capabilities become available.
Custom View APIs are not available in CustomApp sessions; do not mix session types.
Prerequisites
- Connection and Session completed with
CUSTOMVIEWandconnect(token)called. ICustomViewCbkregistered.- If the layout contains
ImageView, callcustomViewSetIconsfirst.
Core APIs
| Method | Description |
|---|---|
setCXRCustomViewCbk(ICustomViewCbk) | Register Custom View callbacks |
customViewSetIcons(String) | Icon list JSON array string |
customViewOpen(String) | Full view tree JSON for initial open |
customViewUpdate(String) | Incremental update JSON array |
customViewClose() | Close the current Custom View |
customViewIsOpen() | Query whether the view is still open |
ICustomViewCbk callbacks
| Callback | Description |
|---|---|
onCustomViewOpened() | View opened on glasses; scene building complete |
onCustomViewUpdated() | Incremental update applied |
onCustomViewClosed() | View closed |
onCustomViewIconsSent() | Icons delivered successfully |
onCustomViewError(code, msg?) | Error; clear “opened” state |
Recommended call order
- Link ready:
onCXRLConnected(true)andonGlassBtConnected(true). customViewSetIcons— required when usingImageView; call after link ready.customViewOpen— call after link ready.- After
onCustomViewOpened, use audio/photo sub-capabilities. customViewUpdatefor partial refresh.customViewClosewhen done.
Constraints
ImageViewnamemust match an icon entryname.- Each node
props.idmust be unique forcustomViewUpdatetargeting. - Field names and units (
dp/sp) must match the protocol. - Call audio/photo only after
onCustomViewOpened. customViewSetIconsandcustomViewOpenrequire CXRL connected and Bluetooth ready.
## CustomView JSON Schema
### 1. View tree (customViewOpen)
Each node is a JSON object:
```json
{
“type”: “LinearLayout”,
“props”: { “id”: “root”, “layout_width”: “match_parent”, “layout_height”: “match_parent” },
“children”: []
}
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Node type (see table below) |
props | object | Yes | Node properties |
children | array | No | Child nodes; omit for leaf nodes |
Supported type values:
| type | Description |
|---|---|
LinearLayout | Linear layout container |
RelativeLayout | Relative layout container |
TextView | Text |
ImageView | Image (references pre-sent icon) |
2. Common layout fields
Shared across multiple type values in props:
| Field | Type | Required | Values / format | Description |
| ----------------- | ------ | -------- | ------------------------ | ----------------------------------------------------------- | ------- | ----- |
| id | string | Yes | [a-zA-Z0-9_]+ | Unique node id for customViewUpdate |
| layout_width | string | Yes | match_parent | wrap_content | {N}dp | Width |
| layout_height | string | Yes | Same as width | Height |
| marginStart | string | No | {N}dp | Start margin |
| marginEnd | string | No | {N}dp | End margin |
| marginTop | string | No | {N}dp | Top margin |
| marginBottom | string | No | {N}dp | Bottom margin |
| paddingStart | string | No | {N}dp | Start padding |
| paddingEnd | string | No | {N}dp | End padding |
| paddingTop | string | No | {N}dp | Top padding |
| paddingBottom | string | No | {N}dp | Bottom padding |
| backgroundColor | string | No | #RRGGBB or #AARRGGBB | Background; rendered with green-channel emphasis on glasses |
Units: Use explicit
dporspsuffixes; bare numbers may be auto-suffixed on some clients — prefer explicit units.
Colors: Glasses map colors toward a green-channel display style; do not assume full-color reproduction.
3. LinearLayout props
| Field | Type | Required | Values | Description |
| ---------------- | ------ | -------- | --------------- | ----------------------- | ------------------- | ----- | -------- | ------- | ----- | --------------- |
| orientation | string | Yes | vertical | horizontal | Layout direction |
| gravity | string | No | center | center_vertical | center_horizontal | top | bottom | start | end | Child alignment |
| layout_gravity | string | No | Same as gravity | Alignment within parent |
When serialized, paddingStart / paddingEnd map to JSON keys paddingLeft / paddingRight.
4. RelativeLayout props
In addition to common layout fields:
| Field | Type | Required | Values | Description |
| --------------------------- | ------ | -------- | ---------------- | --------------------------- | --------------------------------------------- |
| layout_toStartOf | string | No | Target node id | Position to start of target |
| layout_toEndOf | string | No | Target node id | Position to end of target |
| layout_above | string | No | Target node id | Above target |
| layout_below | string | No | Target node id | Below target |
| layout_alignStart | string | No | Target node id | Align start with target |
| layout_alignEnd | string | No | Target node id | Align end with target |
| layout_alignTop | string | No | Target node id | Align top with target |
| layout_alignBottom | string | No | Target node id | Align bottom with target |
| layout_alignBaseLine | string | No | Target node id | Align baseline with target |
| layout_aliginParentStart | string | No | true | false | Align to parent start (protocol key spelling) |
| layout_aliginParentEnd | string | No | true | false | Align to parent end |
| layout_aliginParentTop | string | No | true | false | Align to parent top |
| layout_aliginParentBottom | string | No | true | false | Align to parent bottom |
| layout_centerInParent | string | No | true | false | Center in parent |
| layout_centerHorizontal | string | No | true | false | Horizontal center |
| layout_centerVertical | string | No | true | false | Vertical center |
Relative constraint values reference other nodes’ props.id in the same tree.
5. TextView props
| Field | Type | Required | Values | Description |
| ----------- | ------ | -------- | ------------------------ | ----------------- | ------------------- | ---------- | ----- | ----- | -------- | -------------- |
| text | string | Yes | Any text | Display content |
| textColor | string | No | #RRGGBB or #AARRGGBB | Text color |
| textSize | string | No | {N}sp | Font size |
| gravity | string | No | center | center_vertical | center_horizontal | start | end | top | bottom | Text alignment |
| textStyle | string | No | bold | italic | bold_italic | Font style |
6. ImageView props
| Field | Type | Required | Values | Description |
| ----------- | ------ | -------- | ------------------------ | ----------------------------------------- | --------------- | ------------ | --------- | ----------- | -------- | -------- | ---------------------------- |
| name | string | Yes | Matches icon list name | References icon from customViewSetIcons |
| scaleType | string | No | center | center_crop | center_inside | fit_center | fit_end | fit_start | fit_xy | matrix | Scale mode; default center |
7. Icon resources (customViewSetIcons)
JSON array string:
[
{ “name”: “icon1”, “data”: “<Base64-encoded PNG>” },
{ “name”: “icon2”, “data”: “<Base64-encoded PNG>” }
]
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Icon id; matches ImageView.props.name |
data | string | Yes | Base64 PNG (Base64.NO_WRAP recommended) |
8. Incremental update (customViewUpdate)
JSON array string:
[
{
“action”: “update”,
“id”: “textView”,
“props”: { “text”: “Hello Rokid 1” }
},
{
“action”: “update”,
“id”: “imageView”,
“props”: { “name”: “icon2” }
}
]
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Always “update” |
id | string | Yes | Target node props.id |
props | object | Yes | Changed fields only |
When switching ImageView icons, the new name must already exist in customViewSetIcons.
9. Full example
customViewOpen:
{
“type”: “LinearLayout”,
“props”: {
“id”: “root”,
“layout_width”: “match_parent”,
“layout_height”: “match_parent”,
“marginTop”: “160dp”,
“marginBottom”: “80dp”,
“backgroundColor”: “#FF000000”,
“orientation”: “vertical”,
“gravity”: “center_horizontal”
},
“children”: [
{
“type”: “TextView”,
“props”: {
“id”: “textView”,
“layout_width”: “wrap_content”,
“layout_height”: “wrap_content”,
“text”: “Hello World”,
“textColor”: “#00FF00”,
“textSize”: “16sp”,
“gravity”: “center”,
“textStyle”: “bold”,
“paddingStart”: “16dp”,
“paddingEnd”: “16dp”
}
},
{
“type”: “ImageView”,
“props”: {
“id”: “imageView”,
“layout_width”: “120dp”,
“layout_height”: “120dp”,
“name”: “icon1”,
“scaleType”: “center”
}
}
]
}
Next steps
After scene building: Audio, Photo Capture. Custom Commands are not available in CustomView sessions.
Appendix: reference sample
RenewCXRLSample SessionHubViewModel and dataBean/selfView/ helpers.