Une fois que vous avez demandé et obtenu les autorisations nécessaires, votre application peut accéder au matériel des lunettes IA. Pour accéder au matériel des lunettes (au lieu de celui du téléphone), vous devez utiliser un contexte projeté.
Il existe deux méthodes principales pour obtenir un contexte projeté, en fonction de l'endroit où votre code s'exécute :
Obtenir un contexte projeté si votre code s'exécute dans une activité de lunettes IA
Si le code de votre application s'exécute à partir de l'activité de vos lunettes d'IA, son propre contexte d'activité est déjà un contexte projeté. Dans ce scénario, les appels effectués dans cette activité peuvent déjà accéder au matériel des lunettes.
Obtenir un contexte projeté si votre code s'exécute dans un composant d'application de téléphone
Si une partie de votre application en dehors de votre activité de lunettes IA (telle qu'une activité de téléphone ou un service) doit accéder au matériel des lunettes, elle doit obtenir explicitement un contexte projeté. Pour ce faire, utilisez la méthode 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
}
Vérifier la validité
Après avoir créé le contexte projeté, surveillez ProjectedContext.isProjectedDeviceConnected. Bien que cette méthode renvoie true, le contexte projeté reste valide pour l'appareil connecté, et l'activité ou le service de votre application mobile (comme CameraManager) peuvent accéder au matériel des lunettes IA.
Nettoyer à la déconnexion
Le contexte projeté est lié au cycle de vie de l'appareil connecté. Il est donc détruit lorsque l'appareil se déconnecte. Lorsque l'appareil se déconnecte, ProjectedContext.isProjectedDeviceConnected renvoie false. Votre application doit être à l'écoute de ce changement et nettoyer tous les services système (tels qu'un CameraManager) ou les ressources que votre application a créés à l'aide de ce contexte projeté.
Réinitialiser lors de la reconnexion
Lorsque l'appareil lunettes IA se reconnecte, votre application peut obtenir une autre instance de contexte projeté à l'aide de createProjectedDeviceContext(), puis réinitialiser les services ou ressources système à l'aide du nouveau contexte projeté.
Accéder à l'audio via Bluetooth
Actuellement, les lunettes IA se connectent à votre téléphone en tant qu'appareil audio Bluetooth standard. Le casque et les profils A2DP (Advanced Audio Distribution Profile) sont pris en charge. Cette approche permet à n'importe quelle application Android compatible avec les entrées ou sorties audio de fonctionner sur des lunettes, même si elle n'a pas été conçue spécifiquement pour les lunettes. Dans certains cas, l'utilisation du Bluetooth peut mieux fonctionner pour le cas d'utilisation de votre application que l'accès au matériel des lunettes à l'aide d'un contexte projeté.
Comme pour tout appareil audio Bluetooth standard, l'autorisation d'accorder l'autorisation RECORD_AUDIO est contrôlée par le téléphone et non par les lunettes.
Capturer une image avec la caméra des lunettes d'IA
Pour capturer une image avec l'appareil photo des lunettes IA, configurez et associez le ImageCapture cas d'utilisation de CameraX à l'appareil photo des lunettes en utilisant le contexte approprié pour votre application :
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))
}
Points clés concernant le code
- Obtient une instance de
ProcessCameraProviderà l'aide du contexte de l'appareil projeté. - Dans le champ du contexte projeté, la caméra principale des lunettes d'IA, orientée vers l'extérieur, correspond à
DEFAULT_BACK_CAMERAlors de la sélection d'une caméra. - Une vérification de pré-association utilise
cameraProvider.hasCamera(cameraSelector)pour vérifier que la caméra sélectionnée est disponible sur l'appareil avant de continuer. - Utilise Camera2 Interop avec
Camera2CameraInfopour lire leCameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAPsous-jacent, ce qui peut être utile pour les vérifications avancées des résolutions compatibles. - Un
ResolutionSelectorpersonnalisé est conçu pour contrôler précisément la résolution de l'image de sortie pourImageCapture. - Crée un cas d'utilisation
ImageCaptureconfiguré avec unResolutionSelectorpersonnalisé. - Associe le cas d'utilisation
ImageCaptureau cycle de vie de l'activité. Cela gère automatiquement l'ouverture et la fermeture de l'appareil photo en fonction de l'état de l'activité (par exemple, en arrêtant l'appareil photo lorsque l'activité est suspendue).
Une fois la caméra des lunettes d'IA configurée, vous pouvez capturer une image avec la classe ImageCapture de CameraX. Consultez la documentation de CameraX pour savoir comment utiliser takePicture() pour capturer une image.
Filmer une vidéo avec la caméra des lunettes d'IA
Pour capturer une vidéo au lieu d'une image avec la caméra des lunettes IA, remplacez les composants ImageCapture par les composants VideoCapture correspondants et modifiez la logique d'exécution de la capture.
Les principaux changements consistent à utiliser un autre cas d'utilisation, à créer un autre fichier de sortie et à lancer la capture à l'aide de la méthode d'enregistrement vidéo appropriée.
Pour en savoir plus sur l'API VideoCapture et son utilisation, consultez la documentation sur la capture vidéo de CameraX.
Le tableau suivant indique la résolution et la fréquence d'images recommandées en fonction du cas d'utilisation de votre application :
| Cas d'utilisation | Résolution | Fréquence d'images |
|---|---|---|
| Communication vidéo | 1 280 x 720 | 15 FPS |
| Vision par ordinateur | 640 x 480 | 10 FPS |
| Streaming vidéo IA | 640 x 480 | 1 FPS |
Accéder au matériel d'un téléphone depuis une activité de lunettes IA
Une activité de lunettes IA peut également accéder au matériel du téléphone (comme l'appareil photo ou le micro) en utilisant createHostDeviceContext(context) pour obtenir le contexte de l'appareil hôte (téléphone) :
// 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
Lorsque vous accédez à du matériel ou à des ressources spécifiques à l'appareil hôte (téléphone) dans une application hybride (une application contenant à la fois des expériences mobiles et des expériences avec des lunettes d'IA), vous devez sélectionner explicitement le contexte approprié pour vous assurer que votre application peut accéder au matériel approprié :
- Utilisez le contexte
Activitydu téléphoneActivityouProjectedContext.createHostDeviceContext()pour obtenir le contexte du téléphone. - N'utilisez pas
getApplicationContext(), car le contexte de l'application peut renvoyer de manière incorrecte le contexte des lunettes IA si une activité des lunettes était le composant lancé le plus récemment.