Камера в Surface Duo

Передняя и задняя камеры

Surface Duo использует один аппаратный компонент для получения изображения с передней и задней камер (в зависимости от положения устройства). При переключении камер изображение переворачивается таким образом, чтобы селфи отображались правильно.

Блокировка ориентации

Запрос на блокировку ориентации в книжном или альбомном формате приведет к отображению приложения в рамках, если оно размещается на одном экране, а на другом экране присутствует другое приложение (или средство запуска). Если представление камеры отображается с рамками при заблокированной ориентации, значит поворот представления камеры отличается от поворота приложения. Ваше приложение может:

  • показывать сообщение;
  • поворачивать изображение с камеры.

Установка блокировки ориентации

android:screenOrientation="portrait"

Или в коде:

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

Отображение сообщения

Чтобы отобразить сообщение о камере при блокировке в книжной ориентации, используйте класс PortraitLockHelper. Этот вспомогательный класс может быть привязан к onCreate с помощью прослушивателя для определения состояний, когда должно отображаться сообщение:

portraitHelper = new PortraitLockHelper(this);
portraitHelper.StateListener = new PortraitLockHelper.PortraitStateListener() {
    @Override
    public void PortraitStateChanged(int state) {
//...
    if((state & PortraitLockHelper.PORTRAIT_STATE_LETTERBOXED_90) > 0 ){
        if(showRotationMessage){
            rotationMessageView.setVisibility(View.VISIBLE);
        }
//...
    }
}

Полную реализацию см. в коде примера для камеры на сайте GitHub.

Поворот изображения с камеры

Класс PortraitLockHelper можно использовать для определения поворота устройства и соответствующего поворота потокового изображения с камеры. Чтобы реализовать это, убедитесь, что вы используете TextureView, а не SurfaceView в качестве области предварительного просмотра. TextureView можно преобразовать, например textureView.setRotation(90) повернет изображение камеры на 90 градусов. После этого потребуется использовать setScaleX и setScaleY, чтобы изменить пропорции для корректировки размеров повернутого экрана.

В примере кода для камеры используются следующие значения преобразования для каждого состояния устройства:

Состояние Поворот изображения с камеры Масштаб по оси X Масштаб по оси Y
значение по умолчанию 0 1 1
Перевернутый 0 1 1
Развернутый 90 4/3 4/3
В рамках с поворотом на 90 градусов 90 4/3 4/3
В рамках с поворотом на 270 градусов 270 4/3 4/3

Пример кода включает кнопки для включения или отключения поворота. Код, необходимый для адаптации к каждому состоянию устройства, см. в разделе о реализации PortraitStateListener.

Камера с изменением размера и без блокировки ориентации

Если для приложения не нужно блокировать ориентацию, можно использовать тот же код для поворота изображения с камеры. Подробные сведения см. в разделе о повороте изображения с камеры выше.

Чтобы гарантировать отсутствие блокировки ориентации, используйте следующий код:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

CameraX

Если вы создаете новое приложение или планируете обновить код для камеры, API CameraX предоставит вам современные базовые возможности. Пример CameraXBasic от Google на сайте GitHub отлично работает на Surface Duo, но для оптимизации работы внесите два небольших изменения:

AndroidManifest.xml

android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"

MainActivity.kt

override fun onWindowFocusChanged(hasFocus: Boolean) {
    super.onWindowFocusChanged(hasFocus)
    if(hasFocus){
        container.postDelayed({
            container.systemUiVisibility = FLAGS_FULLSCREEN
        }, IMMERSIVE_FLAG_TIMEOUT)
    }
}

Такие изменения оптимизируют развертывание и свертывание приложения, а также изменение фокуса между приложением камеры и элементами на другом экране.

Примеры