L'esperienza degli occhiali AI si basa sul framework Activity
API Android esistente e include concetti aggiuntivi per supportare gli aspetti unici degli
occhiali AI. A differenza dei visori XR che eseguono un APK completo sul dispositivo, gli occhiali AI utilizzano
un'attività dedicata che viene eseguita all'interno dell'app esistente dello smartphone. Questa attività
viene proiettata dal dispositivo host agli occhiali AI.
Per creare l'esperienza di occhiali AI della tua app, estendi l'app per smartphone esistente creando un nuovo Activity proiettato per gli occhiali AI. Questa attività funge
da punto di accesso principale per l'avvio della tua app sugli occhiali AI. Questo approccio
semplifica lo sviluppo perché puoi condividere e riutilizzare la logica di business tra
le esperienze dello smartphone e degli occhiali AI.
Compatibilità delle versioni
Controlla i requisiti di compatibilità dell'SDK Android per l'SDK Jetpack XR.
Dipendenze
Aggiungi le seguenti dipendenze della libreria per gli occhiali AI:
Alla moda
dependencies {
implementation "androidx.xr.runtime:runtime:1.0.0-alpha12"
implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha11"
implementation "androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11"
implementation "androidx.xr.projected:projected:1.0.0-alpha06"
implementation "androidx.xr.arcore:arcore:1.0.0-alpha12"
}
Kotlin
dependencies {
implementation("androidx.xr.runtime:runtime:1.0.0-alpha12")
implementation("androidx.xr.glimmer:glimmer:1.0.0-alpha11")
implementation("androidx.xr.glimmer:glimmer-google-fonts:1.0.0-alpha11")
implementation("androidx.xr.projected:projected:1.0.0-alpha06")
implementation("androidx.xr.arcore:arcore:1.0.0-alpha12")
}
Dichiarare l'attività nel file manifest dell'app
Come per altri tipi di attività, devi dichiarare la tua attività nel file manifest dell'app affinché il sistema possa visualizzarla ed eseguirla.
<application>
<activity
android:name="com.example.xr.projected.GlassesMainActivity"
android:exported="true"
android:requiredDisplayCategory="xr_projected"
android:label="Example AI Glasses activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
</application>
Punti chiave sul codice
- Specifica
xr_projectedper l'attributoandroid:requiredDisplayCategoryper indicare al sistema che questa attività deve utilizzare un contesto proiettato per accedere all'hardware da un dispositivo connesso.
Crea la tua attività
Successivamente, creerai una piccola attività che può visualizzare qualcosa sugli occhiali AI ogni volta che il display è acceso.
@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)) } }
Punti chiave sul codice
- Consente di utilizzare le API con consenso della libreria Jetpack Projected.
GlassesMainActivityestendeComponentActivity, proprio come ti aspetteresti nello sviluppo mobile.- Poiché non tutti gli occhiali AI hanno un display, controlla se il dispositivo ha un display utilizzando
ProjectedDeviceController. - Il blocco
setContentall'interno della funzioneonCreatedefinisce la radice dell'albero della UI componibile per l'attività. Implementerai il componibileHomeScreenutilizzando Jetpack Compose Glimmer. - Inizializza l'interfaccia utente durante il metodo
onCreatedell'attività (vedi ciclo di vita dell'attività proiettato). - Per prepararsi alle funzionalità correlate alla videocamera che
accedono all'hardware degli occhiali, richiedi le autorizzazioni hardware registrando
un launcher di autorizzazioni, definendo le funzioni
hasCameraPermissionerequestHardwarePermissionse controllando se le autorizzazioni sono state concesse prima di chiamareinitializeGlassesFeatures.
Implementare il composable
L'attività che hai creato fa riferimento a una funzione componibile HomeScreen che
devi implementare. Il seguente codice utilizza Jetpack Compose Glimmer per
definire un componibile che può visualizzare del testo sul display degli occhiali AI:
@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") } } }
Punti chiave sul codice
- Come hai definito in precedenza nell'attività, la funzione
HomeScreeninclude i contenuti componibili che l'utente vede quando il display degli occhiali AI è acceso. - Il componente Jetpack Compose Glimmer
Textmostra il testo "Hello, AI Glasses!" sul display degli occhiali. - L'intent Jetpack Compose Glimmer
Buttonchiude l'attività chiamandofinish()tramiteonClosenell'attività degli occhiali AI.
Controllare se gli occhiali AI sono connessi
Per determinare se gli occhiali AI di un utente sono connessi al suo smartphone prima di avviare l'attività, utilizza il metodo ProjectedContext.isProjectedDeviceConnected. Questo metodo
restituisce un Flow<Boolean> che la tua app può osservare per ricevere aggiornamenti in tempo reale sullo stato della connessione.
Avviare l'attività
Ora che hai creato un'attività di base, puoi avviarla sugli occhiali. Per accedere all'hardware degli occhiali, la tua app deve avviare l'attività con opzioni specifiche che indicano al sistema di utilizzare un contesto proiettato, come mostrato nel codice seguente:
val options = ProjectedContext.createProjectedActivityOptions(context) val intent = Intent(context, GlassesMainActivity::class.java) context.startActivity(intent, options.toBundle())
Il metodo createProjectedActivityOptions in ProjectedContext
genera le opzioni necessarie per avviare l'attività in un contesto proiettato.
Il parametro context può essere un contesto dello smartphone o degli occhiali.
Passaggi successivi
Ora che hai creato la tua prima attività per gli occhiali AI, esplora altri modi per estenderne la funzionalità:
- Gestire l'uscita audio utilizzando la sintesi vocale
- Gestire l'input audio utilizzando il riconoscimento vocale automatico
- Creare UI con Jetpack Compose Glimmer
- Accedere all'hardware degli occhiali AI