Después de solicitar y obtener los permisos necesarios, tu app puede acceder al hardware de los lentes con IA. La clave para acceder al hardware de los lentes (en lugar del hardware del teléfono) es usar un contexto proyectado.
Existen dos formas principales de obtener un contexto proyectado, según dónde se ejecute tu código:
Obtén un contexto proyectado si tu código se ejecuta en una actividad de lentes con IA
Si el código de tu app se ejecuta desde la actividad de tus lentes con IA, su propio contexto de actividad ya es un contexto proyectado. En esta situación, las llamadas realizadas dentro de esa actividad ya pueden acceder al hardware de los lentes.
Obtener un contexto proyectado si tu código se ejecuta en el componente de la app para teléfonos
Si una parte de tu app fuera de la actividad de los lentes con IA (como una actividad del teléfono o un servicio) necesita acceder al hardware de los lentes, debe obtener explícitamente un contexto proyectado. Para ello, usa el método createProjectedDeviceContext():
// From a phone Activity, get a context for the AI glasses
try {
val glassesContext = ProjectedContext.createProjectedDeviceContext(this)
// Now use glassesContext to access glasses' system services
} catch (e: IllegalStateException) {
// Projected device was not found
}
Cómo verificar la validez
Después de crear el contexto proyectado, supervisa ProjectedContext.isProjectedDeviceConnected. Si bien este método devuelve true, el contexto proyectado sigue siendo válido para el dispositivo conectado, y la actividad o el servicio de la app para teléfonos (como un CameraManager) pueden acceder al hardware de los lentes con IA.
Limpieza al desconectar
El contexto proyectado está vinculado al ciclo de vida del dispositivo conectado, por lo que se destruye cuando se desconecta el dispositivo. Cuando se desconecta el dispositivo, ProjectedContext.isProjectedDeviceConnected devuelve false. Tu app debe detectar este cambio y limpiar los servicios del sistema (como un CameraManager) o los recursos que creó con ese contexto proyectado.
Reinicializar al reconectar
Cuando se vuelve a conectar el dispositivo de anteojos con IA, tu app puede obtener otra instancia de contexto proyectado con createProjectedDeviceContext() y, luego, reinicializar cualquier servicio o recurso del sistema con el nuevo contexto proyectado.
Acceder al audio por Bluetooth
Actualmente, los lentes con IA se conectan a tu teléfono como un dispositivo de audio Bluetooth estándar. Se admiten tanto el visor como los perfiles A2DP (perfil de distribución de audio avanzado). Con este enfoque, cualquier app para Android que admita entrada o salida de audio funcionará en los lentes, incluso si no se creó específicamente para admitirlos. En algunos casos, usar Bluetooth puede funcionar mejor para el caso de uso de tu app como alternativa a acceder al hardware de los lentes con un contexto proyectado.
Al igual que con cualquier dispositivo de audio Bluetooth estándar, el permiso para otorgar el permiso de RECORD_AUDIO lo controla el teléfono y no los lentes.
Cómo capturar una imagen con la cámara de los lentes con IA
Para capturar una imagen con la cámara de los lentes con IA, configura y vincula el ImageCapture caso de uso de CameraX a la cámara de los lentes con el contexto correcto para tu app:
private fun startCamera() {
// Get the CameraProvider using the projected context.
val cameraProviderFuture = ProcessCameraProvider.getInstance(
ProjectedContext.createProjectedDeviceContext(this)
)
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Select the camera. When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera.
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
// Check for the presence of a camera before initializing the ImageCapture use case.
if (!cameraProvider.hasCamera(cameraSelector)) {
Log.w(TAG, "The selected camera is not available.")
return@addListener
}
// Get supported streaming resolutions.
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)
val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo)
val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
// Define the resolution strategy.
val targetResolution = Size(1920, 1080)
val resolutionStrategy = ResolutionStrategy(
targetResolution,
ResolutionStrategy.FALLBACK_RULE_CLOSEST_LOWER)
val resolutionSelector = ResolutionSelector.Builder()
.setResolutionStrategy(resolutionStrategy)
.build()
// If you have other continuous use cases bound, such as Preview or ImageAnalysis, you can use Camera2 Interop's CaptureRequestOptions to set the FPS
val fpsRange = Range(30, 30)
val captureRequestOptions = CaptureRequestOptions.Builder()
.setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,fpsRange)
.build()
// Initialize the ImageCapture use case.
val imageCapture = ImageCapture.Builder()
// Optional: Configure resolution, format, etc.
.setResolutionSelector(resolutionSelector)
.build()
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// 4. Bind use cases to camera
cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageCapture)
} catch(exc: Exception) {
// This catches exceptions like IllegalStateException if use case binding fails
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
Puntos clave sobre el código
- Obtiene una instancia de
ProcessCameraProvidercon el contexto del dispositivo proyectado. - Dentro del alcance del contexto proyectado, la cámara principal de los lentes con IA, que apunta hacia afuera, se asigna a
DEFAULT_BACK_CAMERAcuando se selecciona una cámara. - Una verificación previa a la vinculación usa
cameraProvider.hasCamera(cameraSelector)para verificar que la cámara seleccionada esté disponible en el dispositivo antes de continuar. - Usa Camera2 Interop con
Camera2CameraInfopara leer elCameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAPsubyacente, lo que puede ser útil para realizar verificaciones avanzadas de las resoluciones admitidas. - Se compila un
ResolutionSelectorpersonalizado para controlar con precisión la resolución de la imagen de salida paraImageCapture. - Crea un caso de uso de
ImageCaptureque se configura con unResolutionSelectorpersonalizado. - Vincula el caso de uso de
ImageCaptureal ciclo de vida de la actividad. Esto administra automáticamente la apertura y el cierre de la cámara según el estado de la actividad (por ejemplo, detiene la cámara cuando se pausa la actividad).
Después de configurar la cámara de los lentes con IA, puedes capturar una imagen con la clase ImageCapture de CameraX. Consulta la documentación de CameraX para obtener información sobre cómo usar takePicture() para capturar una imagen.
Cómo capturar un video con la cámara de los lentes con IA
Para capturar un video en lugar de una imagen con la cámara de los lentes con IA, reemplaza los componentes ImageCapture por los componentes VideoCapture correspondientes y modifica la lógica de ejecución de la captura.
Los principales cambios implican usar un caso de uso diferente, crear un archivo de salida diferente y, luego, iniciar la captura con el método de grabación de video adecuado.
Para obtener más información sobre la API de VideoCapture y cómo usarla, consulta la documentación de captura de video de CameraX.
En la siguiente tabla, se muestran la resolución y la velocidad de fotogramas recomendadas según el caso de uso de tu app:
| Caso de uso | Resolución | Velocidad de fotogramas |
|---|---|---|
| Comunicación por video | 1280 x 720 | 15 FPS |
| Visión artificial | 640 × 480 | 10 FPS |
| Transmisión de video con IA | 640 × 480 | 1 FPS |
Cómo acceder al hardware de un teléfono desde una actividad de lentes con IA
Una actividad de lentes con IA también puede acceder al hardware del teléfono (como la cámara o el micrófono) con createHostDeviceContext(context) para obtener el contexto del dispositivo host (teléfono):
// From an AI glasses Activity, get a context for the phone
val phoneContext = ProjectedContext.createHostDeviceContext(this)
// Now use phoneContext to access the phone's hardware
Cuando accedas a hardware o recursos específicos del dispositivo host (teléfono) en una app híbrida (una app que contiene experiencias para dispositivos móviles y lentes con IA), debes seleccionar de forma explícita el contexto correcto para asegurarte de que tu app pueda acceder al hardware correcto:
- Usa el contexto
ActivitydelActivitydel teléfono o elProjectedContext.createHostDeviceContext()para obtener el contexto del teléfono. - No uses
getApplicationContext()porque el contexto de la aplicación puede devolver incorrectamente el contexto de los lentes con IA si una actividad de los lentes fue el componente que se inició más recientemente.