После того, как вы запросили и получили необходимые разрешения , ваше приложение сможет получить доступ к аппаратному обеспечению очков с искусственным интеллектом. Ключ к доступу к аппаратному обеспечению очков (а не телефона) — использование проецируемого контекста .
Существует два основных способа получить спроецированный контекст в зависимости от того, где выполняется ваш код:
Получите спроецированный контекст, если ваш код выполняется в активности очков ИИ.
Если код вашего приложения выполняется из активности очков ИИ, его собственный контекст активности уже является проецируемым контекстом. В этом случае вызовы, выполняемые внутри этой активности, уже могут обращаться к аппаратному обеспечению очков.
Получите спроецированный контекст, если ваш код выполняется в компоненте приложения для телефона.
Если часть вашего приложения, не связанная с активностью очков ИИ (например, активность телефона или служба), требует доступа к аппаратному обеспечению очков, она должна явно получить проецируемый контекст. Для этого используйте метод 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
}
Проверить на действительность
После создания проецируемого контекста отслеживайте 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 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))
}
Ключевые моменты кода
- Получает экземпляр
ProcessCameraProvider, используя проецируемый контекст устройства . - В рамках проецируемого контекста основная направленная наружу камера очков ИИ сопоставляется с
DEFAULT_BACK_CAMERAпри выборе камеры. - Предварительная проверка привязки использует
cameraProvider.hasCamera(cameraSelector)для проверки доступности выбранной камеры на устройстве перед продолжением работы. - Использует Camera2 Interop с
Camera2CameraInfoдля чтения базовых характеристикCameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP, что может быть полезно для расширенных проверок поддерживаемых разрешений. - Пользовательский
ResolutionSelectorсоздан для точного управления разрешением выходного изображения дляImageCapture. - Создает вариант использования
ImageCapture, настроенный с помощью пользовательскогоResolutionSelector. - Связывает вариант использования
ImageCaptureс жизненным циклом активности. Это автоматически управляет открытием и закрытием камеры в зависимости от состояния активности (например, останавливает камеру при приостановке активности).
После настройки камеры очков с искусственным интеллектом вы можете сделать снимок с помощью класса ImageCapture класса CameraX. Чтобы узнать об использовании takePicture() для захвата изображения , обратитесь к документации CameraX.
Снимите видео с помощью камеры очков ИИ
Чтобы захватить видео вместо изображения с помощью камеры очков ИИ, замените компоненты ImageCapture соответствующими компонентами VideoCapture и измените логику выполнения захвата.
Основные изменения включают использование другого варианта использования, создание другого выходного файла и запуск захвата с использованием соответствующего метода видеозаписи. Подробнее об API VideoCapture и его использовании см. в документации по видеозахвату CameraX .
В следующей таблице показаны рекомендуемые разрешение и частота кадров в зависимости от варианта использования вашего приложения:
| Вариант использования | Разрешение | Частота кадров |
|---|---|---|
| Видеосвязь | 1280 х 720 | 15 кадров в секунду |
| Компьютерное зрение | 640 х 480 | 10 кадров в секунду |
| Потоковое видео с ИИ | 640 х 480 | 1 кадр в секунду |
Доступ к аппаратному обеспечению телефона с помощью очков ИИ
Активность очков ИИ также может получать доступ к оборудованию телефона (например, камере или микрофону), используя createHostDeviceContext(context) для получения контекста хост-устройства (телефона):
// 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
При доступе к оборудованию или ресурсам, специфичным для хост-устройства (телефона) в гибридном приложении (приложении, содержащем как мобильные возможности, так и возможности очков ИИ), необходимо явно выбрать правильный контекст, чтобы ваше приложение могло получить доступ к правильному оборудованию:
- Используйте контекст
ActivityизActivityтелефона илиProjectedContext.createHostDeviceContext()чтобы получить контекст телефона. - Не используйте
getApplicationContext()поскольку контекст приложения может неправильно вернуть контекст очков ИИ, если активность очков была последним запущенным компонентом.