Rozszerzone funkcje okularów audio i okularów z wyświetlaczem są oparte na Activityinterfejsie API platformy Androida i obejmują dodatkowe koncepcje, które uwzględniają unikalne aspekty tych okularów. W przeciwieństwie do zestawów XR, które uruchamiają na urządzeniu pełny plik APK, okulary audio i okulary wyświetlające korzystają z dedykowanej aktywności, która działa w ramach istniejącej aplikacji na telefonie. Ta aktywność jest wyświetlana z urządzenia hosta na okularach.
Aby utworzyć aplikację na okulary audio i okulary z wyświetlaczem, rozszerz istniejącą aplikację na telefon, tworząc nowy projektowany Activity. Ta aktywność służy jako główny punkt wejścia do aplikacji na okularach. Takie podejście upraszcza proces tworzenia, ponieważ możesz udostępniać i ponownie wykorzystywać logikę biznesową między aplikacją na telefon i aplikacją na okulary.
Zgodność wersji
Sprawdź wymagania dotyczące zgodności pakietu Android SDK w przypadku pakietu Jetpack XR SDK.
Zależności
Dodaj te zależności biblioteki dla okularów audio i okularów z wyświetlaczem:
Dynamiczny
dependencies {
implementation "androidx.xr.runtime:runtime:1.0.0-alpha15"
implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha13"
implementation "androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha13"
implementation "androidx.xr.projected:projected:1.0.0-alpha08"
implementation "androidx.xr.arcore:arcore:1.0.0-alpha14"
}
Kotlin
dependencies {
implementation("androidx.xr.runtime:runtime:1.0.0-alpha15")
implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha13")
implementation("androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha13")
implementation("androidx.xr.projected:projected:1.0.0-alpha08")
implementation("androidx.xr.arcore:arcore:1.0.0-alpha14")
}
Zadeklaruj aktywność w pliku manifestu aplikacji
Podobnie jak w przypadku innych typów aktywności musisz zadeklarować aktywność w pliku manifestu aplikacji, aby system mógł ją zobaczyć i uruchomić.
<application>
<activity
android:name="com.example.xr.projected.ProjectedMainActivity"
android:exported="true"
android:requiredDisplayCategory="android.hardware.display.category.XR_PROJECTED"
android:label="Example activity for audio glasses and display glasses">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.XR_PROJECTED_LAUNCHER"/>
</intent-filter>
</activity>
</application>
Najważniejsze informacje o kodzie
- Określa wartość
android.hardware.display.category.XR_PROJECTEDdla atrybutuandroid:requiredDisplayCategory, aby poinformować system, że jest to prognozowana aktywność, którą można wyświetlać na okularach audio i okularach z wyświetlaczem. android.intent.action.MAINustawia tę aktywność jako domyślną aktywność uruchamiania.android.intent.category.XR_PROJECTED_LAUNCHERto specjalna kategoria, która sprawia, że Twoja planowana aktywność jest wykrywalna za pomocą poleceń głosowych Gemini.Gdy użytkownik wyda polecenie głosowe, używając nazwy aplikacji (np. „Otwórz próbkę katalogu AI”, „Uruchom próbkę katalogu AI” lub „Włącz próbkę katalogu AI”), system użyje tej kategorii, aby znaleźć i uruchomić wyznaczoną aktywność na okularach audio lub okularach z wyświetlaczem.
Tworzenie aktywności
Następnie utworzysz małą aktywność, która będzie wyświetlać coś na okularach z AI, gdy tylko wyświetlacz będzie włączony.
@OptIn(ExperimentalProjectedApi::class) class GlassesMainActivity : ComponentActivity() { private var displayController: ProjectedDisplayController? = null private var isVisualUiSupported by mutableStateOf(false) private var areVisualsOn by mutableStateOf(true) private var isPermissionDenied by mutableStateOf(false) // Register the permissions launcher using the ProjectedPermissionsResultContract. private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> = registerForActivityResult(ProjectedPermissionsResultContract()) { results -> if (results[Manifest.permission.CAMERA] == true) { isPermissionDenied = false initializeGlassesFeatures() } else { // Handle permission denial. isPermissionDenied = true } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { displayController?.close() displayController = null } }) if (hasCameraPermission()) { initializeGlassesFeatures() } else { requestHardwarePermissions() } setContent { GlimmerTheme { HomeScreen( areVisualsOn = areVisualsOn, isVisualUiSupported = isVisualUiSupported, isPermissionDenied = isPermissionDenied, onRetryPermission = { requestHardwarePermissions() }, onClose = { finish() } ) } } } private fun initializeGlassesFeatures() { lifecycleScope.launch { // Check device capabilities val projectedDeviceController = ProjectedDeviceController.create(this@GlassesMainActivity) isVisualUiSupported = projectedDeviceController.capabilities.contains(CAPABILITY_VISUAL_UI) val controller = ProjectedDisplayController.create(this@GlassesMainActivity) displayController = controller val observer = GlassesLifecycleObserver( context = this@GlassesMainActivity, controller = controller, onVisualsChanged = { visualsOn -> areVisualsOn = visualsOn } ) lifecycle.addObserver(observer) } } private fun hasCameraPermission(): Boolean { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED } private fun requestHardwarePermissions() { val params = ProjectedPermissionsRequestParams( permissions = listOf(Manifest.permission.CAMERA), rationale = "Camera access is required to overlay digital content on your physical environment." ) requestPermissionLauncher.launch(listOf(params)) } }
Najważniejsze informacje o kodzie
- Włącza korzystanie z interfejsów API wymagających zgody z biblioteki Jetpack Projected.
GlassesMainActivityrozszerzaComponentActivity, tak jak w przypadku tworzenia aplikacji mobilnych.- Nie wszystkie okulary mają wyświetlacz, więc sprawdza, czy urządzenie ma wyświetlacz, za pomocą funkcji
ProjectedDeviceController. - Blok
setContentw funkcjionCreatedefiniuje korzeń drzewa interfejsu użytkownika Composable dla aktywności. Zaimplementujesz funkcję kompozycyjnąHomeScreenza pomocą Jetpack Compose Glimmer. - Inicjuje interfejs podczas metody
onCreateaktywności (patrz przewidywany cykl życia aktywności). - Aby przygotować się na funkcje związane z kamerą, które uzyskują dostęp do sprzętu okularów, prosi o uprawnienia do sprzętu, rejestrując moduł uruchamiający uprawnienia, definiując funkcje
hasCameraPermissionirequestHardwarePermissionsoraz sprawdzając, czy uprawnienia zostały przyznane przed wywołaniem funkcjiinitializeGlassesFeatures.
Implementowanie funkcji typu „composable”
Utworzone działanie odwołuje się do funkcji HomeScreen, którą musisz wdrożyć. Poniższy kod korzysta z Jetpack Compose Glimmer, aby zdefiniować funkcję kompozycyjną, która może wyświetlać tekst na wyświetlaczu okularów:
@Composable fun HomeScreen( areVisualsOn: Boolean, isVisualUiSupported: Boolean, isPermissionDenied: Boolean, onRetryPermission: () -> Unit, onClose: () -> Unit, modifier: Modifier = Modifier ) { Box( modifier = modifier .surface() .focusable(false) .fillMaxSize(), contentAlignment = Alignment.Center ) { if (isPermissionDenied) { Card( title = { Text("Permission Required") }, action = { Button(onClick = onClose) { Text("Exit") } } ) { Text("Camera access is needed to use AI glasses features.") Button(onClick = onRetryPermission) { Text("Retry") } } } else if (isVisualUiSupported) { Card( title = { Text("Android XR") }, action = { Button(onClick = onClose) { Text("Close") } } ) { if (areVisualsOn) { Text("Hello, AI Glasses!") } else { Text("Display is off. Audio guidance active.") } } } else { Text("Audio Guidance Mode Active") } } }
Najważniejsze informacje o kodzie
- Zgodnie z definicją podaną wcześniej w aktywności funkcja
HomeScreenobejmuje treści, które użytkownik widzi, gdy wyświetlacz okularów jest włączony. - Komponent Jetpack Compose Glimmer
Textwyświetla na wyświetlaczu okularów tekst „Hello, AI Glasses!”. - Komponent Jetpack Compose Glimmer
Buttonzamyka aktywność, wywołującfinish()przezonClosew projektowanej aktywności.
Sprawdzanie, czy okulary audio lub okulary z wyświetlaczem są połączone
Aby przed uruchomieniem aktywności sprawdzić, czy okulary audio lub okulary z wyświetlaczem są połączone z telefonem użytkownika, użyj metody ProjectedContext.isProjectedDeviceConnected. Ta metoda zwraca Flow<Boolean>, które aplikacja może obserwować, aby otrzymywać aktualizacje stanu połączenia w czasie rzeczywistym.
Rozpocznij aktywność
Po utworzeniu podstawowej aktywności możesz uruchomić ją na okularach. Aby uzyskać dostęp do sprzętu okularów, aplikacja musi uruchomić aktywność z określonymi opcjami, które informują system o użyciu prognozowanego kontekstu, jak pokazano w tym kodzie:
val options = ProjectedContext.createProjectedActivityOptions(context) val intent = Intent(context, GlassesMainActivity::class.java) context.startActivity(intent, options.toBundle())
Metoda createProjectedActivityOptions w ProjectedContext
generuje opcje niezbędne do rozpoczęcia aktywności w przewidywanym kontekście.
Parametr context może być kontekstem z telefonu lub okularów.
Dalsze kroki
Po utworzeniu pierwszej aktywności dla okularów audio i okularów z wyświetlaczem możesz poznać inne sposoby rozszerzania ich funkcjonalności:
- Obsługa wyjścia audio za pomocą zamiany tekstu na mowę
- Obsługa danych wejściowych audio za pomocą automatycznego rozpoznawania mowy
- Tworzenie interfejsu za pomocą Jetpack Compose Glimmer
- Dostęp do sprzętu na okularach audio i okularach z wyświetlaczem