Auf Englisch lesen

Freigeben über


Camera on Surface Duo

Front and back camera

Surface Duo uses the same camera hardware for both front and back camera, depending on the device posture. Switching cameras flips the image so that selfies render correctly.

Orientation locking

Requesting the orientation be locked to portrait or landscape will result in letterboxing when the app is on a single screen and the other screen is showing a different app (or the Launcher). When a camera view is orientation-locked and letterboxed, the camera view is at a different rotation than the app. Your app can:

  • Show a message
  • Rotate the camera feed

Set the orientation lock

android:screenOrientation="portrait"

or in code:

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

Show a message

To show a message about the camera when portrait locked, use this PortraitLockHelper class. The helper class can be wired up in onCreate using a listener to detect states when the message should be displayed:

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);
        }
//...
    }
}

See the camera sample code on GitHub for a complete implementation.

Rotate the camera feed

The PortraitLockHelper class can also be used to detect device rotation, and rotate the camera data stream to match. For this to work, you need to make sure you use a TextureView and not a SurfaceView as your preview area. TextureView can be transformed, for example textureView.setRotation(90) will rotate the feed 90 degrees - setScaleX and setScaleY then need to be used to update the aspect ratio to compensate for the rotated screen dimensions.

In the camera sample code the following transform values are used for each device state:

State Camera feed rotation Scale X Scale Y
default 0 1 1
Flipped 0 1 1
Spanned 90 4/3 4/3
Letterboxed 90 90 4/3 4/3
Letterboxed 270 270 4/3 4/3

The sample code includes buttons to enable or disable the rotation. See the PortraitStateListener implementation for the code required to adapt to each device state.

Resizable camera with no orientation lock

If your app does not need to lock the orientation, the same code for rotating the camera feed can be used. Refer to the rotate the camera feed section above.

To ensure there is no orientation lock, use the following code:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

CameraX

If you’re building a new app or planning to upgrade your camera code, adopting the CameraX API will give you a modern base to build on. Google’s CameraXBasic sample on GitHub runs great on the Surface Duo – but there are two small code tweaks that can improve the user experience:

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)
    }
}

These minor updates provide a smoother experience when spanning and unspanning the app, and when focus changes between the camera app and whatever is on the other screen.

Samples