Skip to content

Commit a4980a9

Browse files
committed
add in device capabilty check
1 parent dcc4272 commit a4980a9

File tree

4 files changed

+47
-70
lines changed

4 files changed

+47
-70
lines changed

gradle/libs.versions.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,6 @@ roborazzi-rule = { module = "io.github.takahirom.roborazzi:roborazzi-junit-rule"
246246
validator-push = { module = "com.google.android.wearable.watchface.validator:validator-push", version.ref = "validatorPush" }
247247
wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wearComposeMaterial" }
248248
wear-compose-material3 = { module = "androidx.wear.compose:compose-material3", version.ref = "wearComposeMaterial3" }
249-
androidx-wear-phone-interactions = { group = "androidx.wear", name = "wear-phone-interactions", version.ref = "wearPhoneInteractions" }
250-
androidx-wear-remote-interactions = { group = "androidx.wear", name = "wear-remote-interactions", version.ref = "wearRemoteInteractions" }
251249
androidx-glimmer = { group = "androidx.xr.glimmer", name = "glimmer", version.ref = "xrGlimmer" }
252250
androidx-projected = { group = "androidx.xr.projected", name = "projected", version.ref = "xrProjected" }
253251

xr/src/main/java/com/example/xr/projected/GlassesMainActivity.kt

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,59 +19,68 @@ package com.example.xr.projected
1919
import android.os.Bundle
2020
import androidx.activity.ComponentActivity
2121
import androidx.activity.compose.setContent
22-
import androidx.activity.viewModels
2322
import androidx.compose.foundation.layout.Box
2423
import androidx.compose.foundation.layout.fillMaxSize
2524
import androidx.compose.runtime.Composable
2625
import androidx.compose.runtime.getValue
26+
import androidx.compose.runtime.mutableStateOf
27+
import androidx.compose.runtime.setValue
2728
import androidx.compose.ui.Alignment
2829
import androidx.compose.ui.Modifier
29-
import androidx.lifecycle.LifecycleOwner
3030
import androidx.lifecycle.DefaultLifecycleObserver
31-
import androidx.lifecycle.compose.collectAsStateWithLifecycle
31+
import androidx.lifecycle.LifecycleOwner
3232
import androidx.lifecycle.lifecycleScope
3333
import androidx.xr.glimmer.Button
3434
import androidx.xr.glimmer.Card
3535
import androidx.xr.glimmer.GlimmerTheme
3636
import androidx.xr.glimmer.Text
3737
import androidx.xr.glimmer.surface
3838
import androidx.xr.projected.ProjectedDisplayController
39+
import androidx.xr.projected.ProjectedDeviceController
40+
import androidx.xr.projected.ProjectedDeviceController.Capability.Companion.CAPABILITY_VISUAL_UI
3941
import androidx.xr.projected.experimental.ExperimentalProjectedApi
4042
import kotlinx.coroutines.launch
4143

4244
// [START androidxr_projected_ai_glasses_activity]
4345
@OptIn(ExperimentalProjectedApi::class)
4446
class GlassesMainActivity : ComponentActivity() {
4547

48+
private var displayController: ProjectedDisplayController? = null
49+
private var isVisualUiSupported by mutableStateOf(false)
50+
private var areVisualsOn by mutableStateOf(true)
51+
4652
override fun onCreate(savedInstanceState: Bundle?) {
4753
super.onCreate(savedInstanceState)
48-
val viewModel: GlassesViewModel by viewModels()
54+
55+
lifecycle.addObserver(object : DefaultLifecycleObserver {
56+
override fun onDestroy(owner: LifecycleOwner) {
57+
displayController?.close()
58+
displayController = null
59+
}
60+
})
4961

5062
lifecycleScope.launch {
51-
val controller = ProjectedDisplayController.create(this@GlassesMainActivity)
63+
// [START androidxr_projected_device_capabilities_check]
64+
// Check device capabilities
65+
val projectedDeviceController = ProjectedDeviceController.create(this@GlassesMainActivity)
66+
isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI)
67+
// [END androidxr_projected_device_capabilities_check]
5268

69+
val controller = ProjectedDisplayController.create(this@GlassesMainActivity)
70+
displayController = controller
5371
val observer = GlassesLifecycleObserver(
5472
context = this@GlassesMainActivity,
5573
controller = controller,
56-
onVisualsChanged = viewModel::updateVisuals
74+
onVisualsChanged = { visualsOn -> areVisualsOn = visualsOn }
5775
)
5876
lifecycle.addObserver(observer)
59-
60-
// Cleanup observer to close the controller
61-
lifecycle.addObserver(object : DefaultLifecycleObserver {
62-
override fun onDestroy(owner: LifecycleOwner) {
63-
controller.close()
64-
}
65-
})
6677
}
6778

6879
setContent {
69-
// [required] Use collectAsStateWithLifecycle for safe collection
70-
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
71-
7280
GlimmerTheme {
7381
HomeScreen(
74-
visualsOn = uiState.areVisualsOn,
82+
areVisualsOn = areVisualsOn,
83+
isVisualUiSupported = isVisualUiSupported,
7584
onClose = { finish() }
7685
)
7786
}
@@ -83,7 +92,8 @@ class GlassesMainActivity : ComponentActivity() {
8392
// [START androidxr_projected_ai_glasses_activity_homescreen]
8493
@Composable
8594
fun HomeScreen(
86-
visualsOn: Boolean,
95+
areVisualsOn: Boolean,
96+
isVisualUiSupported: Boolean,
8797
onClose: () -> Unit,
8898
modifier: Modifier = Modifier
8999
) {
@@ -93,19 +103,23 @@ fun HomeScreen(
93103
.fillMaxSize(),
94104
contentAlignment = Alignment.Center
95105
) {
96-
Card(
97-
title = { Text("Android XR") },
98-
action = {
99-
Button(onClick = onClose) {
100-
Text("Close")
106+
if (isVisualUiSupported) {
107+
Card(
108+
title = { Text("Android XR") },
109+
action = {
110+
Button(onClick = onClose) {
111+
Text("Close")
112+
}
113+
}
114+
) {
115+
if (areVisualsOn) {
116+
Text("Hello, AI Glasses!")
117+
} else {
118+
Text("Display is off. Audio guidance active.")
101119
}
102120
}
103-
) {
104-
if (visualsOn) {
105-
Text("Hello, AI Glasses!")
106-
} else {
107-
Text("Display is off. Audio guidance active.")
108-
}
121+
} else {
122+
Text("Audio Guidance Mode Active")
109123
}
110124
}
111125
}

xr/src/main/java/com/example/xr/projected/GlassesViewModel.kt

Lines changed: 0 additions & 35 deletions
This file was deleted.

xr/src/main/java/com/example/xr/projected/PhoneMainActivity.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fun ConnectionScreen() {
7777
)
7878
Spacer(modifier = Modifier.height(32.dp))
7979
val scope = rememberCoroutineScope()
80-
val isGlassesConnected by ProjectedContext.isProjectedDeviceConnected(
80+
val areGlassesConnected by ProjectedContext.isProjectedDeviceConnected(
8181
context,
8282
scope.coroutineContext
8383
).collectAsStateWithLifecycle(initialValue = false)
@@ -92,9 +92,9 @@ fun ConnectionScreen() {
9292
// [END androidxr_projected_start_glasses_activity]
9393
},
9494
colors = ButtonDefaults.buttonColors(
95-
containerColor = if (isGlassesConnected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.error
95+
containerColor = if (areGlassesConnected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.error
9696
),
97-
enabled = isGlassesConnected
97+
enabled = areGlassesConnected
9898
) {
9999
Text(
100100
text = "Launch",
@@ -103,7 +103,7 @@ fun ConnectionScreen() {
103103
}
104104
Spacer(modifier = Modifier.height(32.dp))
105105
Text(
106-
text = "Status: " + if (isGlassesConnected) "Connected" else "Disconnected",
106+
text = "Status: " + if (areGlassesConnected) "Connected" else "Disconnected",
107107
style = MaterialTheme.typography.titleMedium
108108
)
109109
}

0 commit comments

Comments
 (0)