Crea la tua prima attività per gli occhiali con l'AI

Dispositivi XR applicabili
Queste indicazioni ti aiutano a creare esperienze per questi tipi di dispositivi XR.
Occhiali AI

L'esperienza degli occhiali AI si basa sull'API del framework Activity di 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 sugli occhiali AI.

Per creare l'esperienza degli occhiali AI della tua app, estendi l'app per smartphone esistente creando una nuova Activity proiettata 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 per smartphone e occhiali AI.

Compatibilità con le 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:

Groovy

dependencies {
    implementation "androidx.xr.runtime:runtime:1.0.0-alpha12"
    implementation "androidx.xr.glimmer:glimmer:1.0.0-alpha10"
    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-alpha10")
    implementation("androidx.xr.projected:projected:1.0.0-alpha06")
    implementation("androidx.xr.arcore:arcore:1.0.0-alpha12")
}

Dichiara l'attività nel file manifest dell'app

Come per gli altri tipi di attività, devi dichiarare l'attività nel file manifest dell'app affinché il sistema possa vederla 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_projected per l'attributo android:requiredDisplayCategory per indicare al sistema che questa attività deve utilizzare un contesto proiettato per accedere all'hardware da un dispositivo connesso.

Crea l'attività

Ora 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

Implementare il composable

L'attività che hai creato fa riferimento a una funzione composable HomeScreen che devi implementare. Il seguente codice utilizza Jetpack Compose Glimmer per definire una funzione 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 HomeScreen include i contenuti composable che l'utente vede quando il display degli occhiali AI è acceso.
  • Il componente Text di Jetpack Compose Glimmer visualizza il testo "Hello, AI Glasses!" sul display degli occhiali.
  • Il componente Button di Jetpack Compose Glimmer chiude l'attività chiamando finish() tramite onClose nell'attività degli occhiali AI.

Controlla 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 ProjectedContext.isProjectedDeviceConnected metodo. Questo metodo restituisce un Flow<Boolean> che la tua app può osservare per ricevere aggiornamenti in tempo reale sullo stato della connessione.

Avvia 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 seguente codice:

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 del dispositivo degli occhiali.

Passaggi successivi

Ora che hai creato la tua prima attività per gli occhiali AI, esplora altri modi per estenderne la funzionalità: