This post has been republished via RSS; it originally appeared at: Microsoft Developer Blogs - Feed.
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 appFigure 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
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 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