March 13th, 2020

Bring your app to Surface Duo – Step 3

Guy Merin
Senior Director of Engineering

Hello Surface Duo developers!

In our Feb 6th blog post, we shared 3 steps to bring your app to Microsoft Surface Duo, followed by a post on step 1 and how to test your app and step 2 highlighting incremental changes to make to your app

Figure 1: Steps to bring your app to Microsoft Surface Duo 1: Steps to bring your app to Microsoft Surface Duo

This week’s blogpost will share details for Step 3 – How to embrace new Dual Screen features on Surface Duo.

There are multiple ways to take advantage of the dual screens:

  • Access the dual screen APIs directly
  • Helper libraries
  • Screen manager
  • Dedicated layouts & controls we’ll provide

This blog post covers how to access the dual screen APIs in your layout code.

Figure 2: Dual Screen APIs layers

Microsoft Dual Screen APIs:

Display Mask

The most useful API is the DisplayMask, which gives you a RECT with coordinates for the location of the

Use this API to understand if your app and layouts intersects with the mask, and re-positions controls and assets based on their relevant position.

Remember, you can also position controls differently if you’re running on the left screen vs the right screen.

The values you’ll get differ based on the device rotation

A screenshot of a social media post Description automatically generated Figure 3: The Display Mask locationThe Display Mask location

See this sample code:

DisplayMask displayMask = DisplayMask.fromResourcesRect(context);

Int rotation;

List<Rect> masks = displayMask.getBoundingRectsForRotation(rotation);
Rect mask = new Rect();
if(!masks.isEmpty()) {
  mask = masks.get(0);
}

 

Hinge Angle

You can also measure and act on the hinge angle between the two screens. We’ve added the hinge angle as a native sensor, so you can add a listener to retrieve the value as the screens move.

The range of motion is 0-360 degrees, which affects the screen display as shown in the diagram below:

Figure 4: The Hinge Sensor

Adding this code to read the sensor values:

private static final String HINGE_ANGLE_SENSOR_NAME = "Hinge Angle Non-Wakeup";

private SensorManager mSensorManager;

private Sensor mHingeAngleSensor;

private SensorEventListener mSensorListener;

private void setupSensors() {

  mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
  for (Sensor sensor : sensorList) {
    if (sensor.getName().contains(HINGE_ANGLE_SENSOR_NAME)) {
      mHingeAngleSensor = sensor;
    }
  }
  mSensorListener = new SensorEventListener() {
    @Override public void onSensorChanged(final SensorEvent event) {
      if (event.sensor == mHingeAngleSensor) {
        int angle = (int) event.values[0];
      }
    }
    @Override public void onAccuracyChanged(Sensor sensor, int accuracy) {
      //TODO
    }
  };
}

@Override protected void onPause() {
  super.onPause();
  if(mHingeAngleSensor !=null) {
    mSensorManager.unregisterListener(mSensorListener,mHingeAngleSensor);
  }
}

@Override protected void onResume() {
  super.onResume();
  if(mHingeAngleSensor !=null) {
    mSensorManager.registerListener(mSensorListener, mHingeAngleSensor, SensorManager.SENSOR_DELAY_NORMAL);
  }
}

 

Duo Device Capability

We know there’ll be times you want to build something special for Surface Duo devices, so we’ve made it easy to check at run-time with a device capability flag.

Use the code below to detect Surface Duo devices, so it’s easier to maintain one codebase for all device configurations:

Add this code snippet to your code:

private boolean isDualScreenDevice(){
String feature = "com.microsoft.device.display.displaymask";
PackageManager pm = this.getPackageManager();

  if (pm.hasSystemFeature(feature)) {
    Log.i(TAG, "System has feature: " + feature);
    return true;
  } else {
    Log.w(TAG, "System missing feature: " + feature);
    return false;
  }
}

 

*Note: You can also query the device name, but it will hard code the app to the Duo device, so not ideal

Summary:

See these APIs in action in our Sample GIT repos, we got your covered in Java Samples, Kotlin samples in and C# Xamarin Samples, all hosted in GitHub.

Let us know how you are planning to use these APIs and how we can make it easier on you.

And make sure to read our next week blog that will cover our helper functions and a new Dual Screen Layout Control that will speed up your development.

Feedback

We would LOVE to hear from you about your experiences using the SDK, emulator, and your first thoughts on how you can utilize these in YOUR app.

Please reach out using our feedback forum or direct message me on Twitter or GitHub.

And if you haven’t seen those already, we started a series of 1 minute videos to answer the most common questions

Thank you,

Guy Merin, Development Manager, Surface Duo Developer Experience Team

 

Author

Guy Merin
Senior Director of Engineering

An #Android #Developer working on #SurfaceDuo and #DeveloperExperience at @Microsoft. Catch me on our #AndroidDevDay #GitHub #PNW trails or drinking #Coffee

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Caleb D

    Any comments on whether the Duo will eventually be able to run Windows 10X?
    Would it have phone apps so that I could perform basic communication from the Windows side?
    I really don't like Google's privacy record. I would rather have a device that I am in control of and can look at the internals. I don't need all the app store. Perhaps I could dual boot, choosing whether to go into...

    Read more