После того, как вы запросите и получите необходимые разрешения , ваше приложение сможет получить доступ к аппаратному обеспечению очков с искусственным интеллектом. Ключ к доступу к аппаратному обеспечению очков (а не телефона) заключается в использовании проецируемого контекста .
Существует два основных способа получения контекста проекции, в зависимости от того, где выполняется ваш код:
Получите контекст проекции, если ваш код выполняется в активности, использующей очки искусственного интеллекта.
Если код вашего приложения выполняется внутри активности, связанной с очками с искусственным интеллектом, то контекст этой активности уже является проецируемым контекстом. В этом случае вызовы, совершаемые внутри этой активности, уже могут получить доступ к аппаратному обеспечению очков.
Получите контекст выполнения кода в компоненте мобильного приложения.
Если части вашего приложения, находящейся вне среды использования очков с ИИ (например, функция телефона или сервис), требуется доступ к аппаратному обеспечению очков, необходимо явно получить проецируемый контекст. Для этого используйте метод createProjectedDeviceContext() :
@OptIn(ExperimentalProjectedApi::class) private fun getGlassesContext(context: Context): Context? { return try { // From a phone Activity or Service, get a context for the AI glasses. ProjectedContext.createProjectedDeviceContext(context) } catch (e: IllegalStateException) { Log.e(TAG, "Failed to create projected device context", e) null } }
Проверьте достоверность
После создания контекста проекции отслеживайте метод ProjectedContext.isProjectedDeviceConnected . Пока этот метод возвращает true , контекст проекции остается действительным для подключенного устройства, и ваше приложение или служба на телефоне (например, CameraManager ) может получить доступ к аппаратному обеспечению очков с искусственным интеллектом.
Очистка при отключении
Проецируемый контекст привязан к жизненному циклу подключенного устройства, поэтому он уничтожается при отключении устройства. При отключении устройства ProjectedContext.isProjectedDeviceConnected возвращает false . Ваше приложение должно отслеживать это изменение и очищать все системные службы (например, CameraManager ) или ресурсы, созданные вашим приложением с использованием этого проецируемого контекста.
Повторная инициализация при повторном подключении.
Когда устройство с ИИ-очками переподключится, ваше приложение сможет получить еще один экземпляр проецируемого контекста с помощью createProjectedDeviceContext() , а затем повторно инициализировать любые системные службы или ресурсы, используя новый проецируемый контекст.
Доступ к аудио через Bluetooth
В настоящее время очки с поддержкой искусственного интеллекта подключаются к телефону как стандартное аудиоустройство Bluetooth. Поддерживаются как сами очки, так и профили A2DP (Advanced Audio Distribution Profile). Такой подход позволяет любому приложению Android, поддерживающему ввод или вывод звука, работать на очках, даже если они не были специально разработаны для работы с очками. В некоторых случаях использование Bluetooth может быть более эффективным для вашего приложения в качестве альтернативы доступу к аппаратному обеспечению очков через контекст проекции.
Как и в случае с любым стандартным Bluetooth-аудиоустройством, разрешение на предоставление параметра RECORD_AUDIO контролируется телефоном, а не очками.
Сделайте снимок с помощью камеры очков с искусственным интеллектом.
Чтобы сделать снимок с помощью камеры очков с искусственным интеллектом, настройте и свяжите сценарий использования ImageCapture модуля CameraX с камерой очков, используя правильный контекст для вашего приложения:
private fun startCameraOnGlasses(activity: ComponentActivity) { // 1. Get the CameraProvider using the projected context. // When using the projected context, DEFAULT_BACK_CAMERA maps to the AI glasses' camera. val projectedContext = try { ProjectedContext.createProjectedDeviceContext(activity) } catch (e: IllegalStateException) { Log.e(TAG, "AI Glasses context could not be created", e) return } val cameraProviderFuture = ProcessCameraProvider.getInstance(projectedContext) cameraProviderFuture.addListener({ val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get() val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA // 2. Check for the presence of a camera. if (!cameraProvider.hasCamera(cameraSelector)) { Log.w(TAG, "The selected camera is not available.") return@addListener } // 3. Query supported streaming resolutions using Camera2 Interop. val cameraInfo = cameraProvider.getCameraInfo(cameraSelector) val camera2CameraInfo = Camera2CameraInfo.from(cameraInfo) val cameraCharacteristics = camera2CameraInfo.getCameraCharacteristic( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP ) // 4. 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() // 5. 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, 60) val captureRequestOptions = CaptureRequestOptions.Builder() .setCaptureRequestOption(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange) .build() // 6. Initialize the ImageCapture use case with options. val imageCapture = ImageCapture.Builder() // Optional: Configure resolution, format, etc. .setResolutionSelector(resolutionSelector) .build() try { // Unbind use cases before rebinding. cameraProvider.unbindAll() // Bind use cases to camera using the Activity as the LifecycleOwner. cameraProvider.bindToLifecycle( activity, cameraSelector, imageCapture ) } catch (exc: Exception) { Log.e(TAG, "Use case binding failed", exc) } }, ContextCompat.getMainExecutor(activity)) }
Основные моменты, касающиеся кода.
- Получает экземпляр
ProcessCameraProvider, используя контекст проецируемого устройства . - В рамках предполагаемого контекста основная, направленная наружу камера очков с искусственным интеллектом сопоставляется с камерой
DEFAULT_BACK_CAMERAпри выборе камеры. - Предварительная проверка с помощью
cameraProvider.hasCamera(cameraSelector)подтверждает наличие выбранной камеры на устройстве перед продолжением. - Использует Camera2 Interop с
Camera2CameraInfoдля чтения базового объектаCameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP, что может быть полезно для расширенной проверки поддерживаемых разрешений. - Для точного управления разрешением выходного изображения в
ImageCaptureсоздан специальныйResolutionSelector. - Создает сценарий использования
ImageCapture, настроенный с использованием пользовательскогоResolutionSelector. - Привязывает сценарий использования
ImageCaptureк жизненному циклу активности. Это автоматически управляет открытием и закрытием камеры в зависимости от состояния активности (например, останавливает камеру, когда активность приостановлена).
После настройки камеры очков с искусственным интеллектом вы можете сделать снимок с помощью класса ImageCapture из библиотеки CameraX. Чтобы узнать, как использовать takePicture() для захвата изображения , обратитесь к документации CameraX.
Запишите видео с помощью камеры очков с искусственным интеллектом.
Чтобы с помощью камеры очков с искусственным интеллектом захватывать видео, а не изображение, замените компоненты ImageCapture соответствующими компонентами VideoCapture и измените логику выполнения захвата.
Основные изменения касаются использования другого сценария применения, создания другого выходного файла и запуска захвата с помощью соответствующего метода видеозаписи. Для получения дополнительной информации об API VideoCapture и способах его использования см. документацию по захвату видео CameraX .
В таблице ниже приведены рекомендуемые разрешение и частота кадров в зависимости от сценария использования вашего приложения:
| Вариант использования | Разрешение | Частота кадров |
|---|---|---|
| Видеосвязь | 1280 x 720 | 15 кадров в секунду |
| Компьютерное зрение | 640 x 480 | 10 кадров в секунду |
| Потоковое видео с использованием ИИ | 640 x 480 | 1 кадр в секунду |
Получите доступ к аппаратному обеспечению телефона из приложения, использующего очки с искусственным интеллектом.
Активность AI Glasses также может получить доступ к аппаратному обеспечению телефона (например, к камере или микрофону), используя createHostDeviceContext(context) для получения контекста хост-устройства (телефона):
@OptIn(ExperimentalProjectedApi::class) private fun getPhoneContext(activity: ComponentActivity): Context? { return try { // From an AI glasses Activity, get a context for the phone. ProjectedContext.createHostDeviceContext(activity) } catch (e: IllegalStateException) { Log.e(TAG, "Failed to create host device context", e) null } }
При доступе к оборудованию или ресурсам, специфичным для хост-устройства (телефона) в гибридном приложении (приложении, сочетающем в себе мобильный интерфейс и возможности очков с искусственным интеллектом), необходимо явно выбрать правильный контекст, чтобы убедиться, что ваше приложение может получить доступ к нужному оборудованию:
- Для получения контекста телефона используйте контекст
ActivityизActivityтелефона или вызовите методProjectedContext.createHostDeviceContext(). - Не используйте
getApplicationContext()поскольку контекст приложения может некорректно возвращать контекст очков ИИ, если активность очков была последним запущенным компонентом.