Gdy poprosisz o niezbędne uprawnienia i je uzyskasz, Twoja aplikacja będzie mieć dostęp do sprzętu okularów z AI. Kluczem do uzyskania dostępu do hardware okularów (zamiast hardware telefonu) jest użycie prognozowanego kontekstu.
Istnieją 2 podstawowe sposoby uzyskiwania prognozowanego kontekstu, w zależności od tego, gdzie jest wykonywany kod:
Jak uzyskać prognozowany kontekst, jeśli kod jest uruchamiany w aktywności związanej z okularami AI
Jeśli kod aplikacji jest uruchamiany w ramach aktywności okularów z AI, własny kontekst aktywności jest już prognozowanym kontekstem. W takim przypadku połączenia wykonywane w ramach tej aktywności mogą już korzystać z hardware okularów.
Jak uzyskać prognozowany kontekst, jeśli kod jest uruchamiany w komponencie aplikacji na telefon
Jeśli część aplikacji poza aktywnością związaną z okularami z AI (np. aktywność na telefonie lub usługa) musi mieć dostęp do hardware okularów, musi wyraźnie uzyskać prognozowany kontekst. Aby to zrobić, użyj metody 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
}
Sprawdzanie ważności
Po utworzeniu prognozowanego kontekstu monitoruj
ProjectedContext.isProjectedDeviceConnected. Chociaż ta metoda zwraca wartość true, prognozowany kontekst pozostaje ważny dla połączonego urządzenia, a aktywność lub usługa aplikacji na telefonie (np. CameraManager) może uzyskać dostęp do sprzętu okularów AI.
Czyszczenie po odłączeniu
Prognozowany kontekst jest powiązany z cyklem życia połączonego urządzenia, więc jest niszczony, gdy urządzenie zostanie odłączone. Gdy urządzenie zostanie odłączone, funkcja ProjectedContext.isProjectedDeviceConnected zwróci wartość false. Aplikacja powinna nasłuchiwać tej zmiany i czyścić wszystkie usługi systemowe (np. CameraManager) lub zasoby utworzone przez aplikację przy użyciu tego kontekstu.
Ponowna inicjalizacja po ponownym połączeniu
Gdy urządzenie z okularami AI ponownie się połączy, aplikacja może uzyskać kolejną instancję kontekstu projecji za pomocą createProjectedDeviceContext(), a następnie ponownie zainicjować dowolne usługi systemowe lub zasoby przy użyciu nowego kontekstu projecji.
Dostęp do dźwięku przez Bluetooth
Obecnie okulary AI łączą się z telefonem jako standardowe urządzenie audio Bluetooth. Obsługiwane są zarówno profile zestawu słuchawkowego, jak i A2DP (Advanced Audio Distribution Profile). Dzięki temu każda aplikacja na Androida, która obsługuje wejście lub wyjście audio, może działać na okularach, nawet jeśli nie została specjalnie zaprojektowana do ich obsługi. W niektórych przypadkach używanie Bluetootha może być lepszym rozwiązaniem dla Twojej aplikacji niż uzyskiwanie dostępu do hardware okularów za pomocą prognozowanego kontekstu.
Podobnie jak w przypadku każdego standardowego urządzenia audio Bluetooth, uprawnienie do przyznania uprawnienia RECORD_AUDIO jest kontrolowane przez telefon, a nie przez okulary.
Robienie zdjęć aparatem okularów z AI
Aby zrobić zdjęcie aparatem okularów AI, skonfiguruj i powiąż przypadek użycia ImageCapture CameraX z aparatem okularów, używając kontekstu odpowiedniego dla aplikacji:
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))
}
Najważniejsze informacje o kodzie
- Pobiera instancję
ProcessCameraProviderza pomocą prognozowanego kontekstu urządzenia. - W zakresie prognozowanego kontekstu główny aparat okularów AI skierowany na zewnątrz jest mapowany na
DEFAULT_BACK_CAMERApodczas wybierania aparatu. - Sprawdzanie przed powiązaniem wykorzystuje
cameraProvider.hasCamera(cameraSelector), aby zanim przejdziesz dalej, było wiadomo, czy wybrany aparat jest dostępny na urządzeniu. - Używa Camera2 Interop z
Camera2CameraInfodo odczytywania podstawowejCameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP, co może być przydatne w przypadku zaawansowanych kontroli obsługiwanych rozdzielczości. - Niestandardowy
ResolutionSelectorzostał opracowany, aby precyzyjnie kontrolować rozdzielczość obrazu wyjściowego w przypadkuImageCapture. - Tworzy przypadek użycia
ImageCaptureskonfigurowany za pomocą niestandardowegoResolutionSelector. - Wiąże przypadek użycia
ImageCapturez cyklem życia aktywności. Ta funkcja automatycznie zarządza otwieraniem i zamykaniem aparatu na podstawie stanu aktywności (np. zatrzymuje aparat, gdy aktywność jest wstrzymana).
Po skonfigurowaniu aparatu w okularach z AI możesz zrobić zdjęcie za pomocą klasy ImageCapture CameraX. Więcej informacji o używaniu takePicture() do robienia zdjęć znajdziesz w dokumentacji CameraX.
Nagrywanie filmów aparatem okularów AI
Aby nagrać film zamiast zrobić zdjęcie za pomocą aparatu w okularach z AI, zastąp komponenty ImageCapture odpowiednimi komponentami VideoCapture i zmodyfikuj logikę wykonywania przechwytywania.
Główne zmiany polegają na zastosowaniu innego przypadku użycia, utworzeniu innego pliku wyjściowego i rozpoczęciu przechwytywania za pomocą odpowiedniej metody nagrywania wideo.
Więcej informacji o interfejsie VideoCapture API i sposobie jego używania znajdziesz w dokumentacji CameraX dotyczącej nagrywania filmów.
W tabeli poniżej znajdziesz zalecaną rozdzielczość i liczbę klatek w zależności od zastosowania aplikacji:
| Przypadek użycia | Rozdzielczość | Liczba klatek |
|---|---|---|
| Komunikacja wideo | 1280 x 720 | 15 kl./s |
| Rozpoznawanie obrazów | 640 x 480 | 10 kl./s |
| Strumieniowe przesyłanie wideo z wykorzystaniem AI | 640 x 480 | 1 kl./s |
Dostęp do hardware telefonu z poziomu aktywności na okularach AI
Aktywność na okularach z AI może też uzyskać dostęp do hardware telefonu (np. aparatu lub mikrofonu) za pomocą createHostDeviceContext(context), aby zdobyć kontekst urządzenia hosta (telefonu):
// 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
Gdy w aplikacji hybrydowej (zawierającej zarówno funkcje mobilne, jak i funkcje na okulary AI) uzyskujesz dostęp do hardware lub zasobów, które są specyficzne dla urządzenia hosta (telefonu), musisz wyraźnie wybrać odpowiedni kontekst, aby aplikacja mogła mieć dostęp do właściwego hardware:
- Aby uzyskać kontekst telefonu, użyj kontekstu
ActivityzActivitytelefonu lubProjectedContext.createHostDeviceContext(). - Nie używaj
getApplicationContext(), ponieważ kontekst aplikacji może nieprawidłowo zwrócić kontekst okularów z AI, jeśli aktywność okularów była ostatnio uruchomionym komponentem.