Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Note
Xamarin.Forms users should check out DualScreenInfo and TwoPaneView in the Xamarin.Forms.DualScreen NuGet.
The Xamarin.DuoSDK is for Xamarin.Android developers targeting the Surface Duo. To target Surface Duo and other foldable devices, see the Jetpack Window Manager binding available in Xamarin.AndroidX.Window.
Hinge Sensor
The HingeSensor class can be used to easily listen for a OnSensorChanged event and get the updated hinge angle value. Add the DuoSDK NuGet to your application before using the Microsoft.Device.Display namespace and HingeSensor class.
using Microsoft.Device.Display;
// ...
HingeSensor hingeSensor;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
hingeSensor = new HingeSensor(this);
}
protected override void OnResume()
{
base.OnResume();
if (hingeSensor?.HasHinge ?? false)
{
hingeSensor.OnSensorChanged += HingeSensor_OnSensorChanged;
hingeSensor.StartListening();
}
}
protected override void OnPause()
{
base.OnPause();
if (hingeSensor?.HasHinge ?? false)
{
hingeSensor.StopListening();
hingeSensor.OnSensorChanged -= HingeSensor_OnSensorChanged;
}
}
private void HingeSensor_OnSensorChanged(object sender, HingeSensor.HingeSensorChangedEventArgs e)
{
Console.WriteLine($"Hinge Sensor Changed: {e.HingeAngle}");
}
IsSurfaceDuoDevice
public bool IsDeviceSurfaceDuo(Context context, string feature = "com.microsoft.device.display.displaymask")
=> context?.PackageManager?.HasSystemFeature(feature) ?? false;
IsAppSpanned
The Xamarin.DuoSdk contains a ScreenHelper class which you can initialize and use to detect if the app is spanned:
public bool IsAppSpanned()
{
var screenHelper = new ScreenHelper();
// If initialize returns false, it's not a Duo device, can't be spanned
if (!screenHelper.Initialize(this))
return false;
return screenHelper.IsDualMode;
}
If you want to retrieve the bounds for the location of the hinge mask, you can use the GetHingeBoundsDip() method:
var hingeBoundsRect = screenHelper.GetHingeBoundsDip();
Display Mask
Add the DuoSDK NuGet to use these APIs in your project.
using Microsoft.Device.Display;
Methods
Static methods
| Method | Description |
|---|---|
| FromResourcesRect(Context context) | Creates the display mask according to config_mainBuiltInDisplayMaskRect. |
| FromResourcesRectApproximation(Context context) | Creates the display mask according to config_mainBuiltInDisplayMaskRectApproximation, which is the closest rectangle-base approximation of the mask. |
Object methods
| Method | Description |
|---|---|
| GetBoundingRects() | Returns a list of Rects, each of which is the bounding rectangle for a non-functional area on the display. |
| GetBoundingRectsForRotation(SurfaceOrientation rotation) | Returns a list of Rects with respect to the rotation, each of which is the bounding rectangle for a non-functional area on the display. |
| GetBounds() | Returns the bounding region of the mask. |
Example
Getting a display mask rect
var displayMask = DisplayMask.FromResourcesRect(context);
var masks = displayMask.GetBoundingRectsForRotation(rotation); // pass in orientation (test with 0)
var mask = new Rect();
if(masks?.Any() ?? false) {
mask = masks.First();
// layout around masked area
}
Public methods
FromResourcesRect
public static DisplayMask FromResourcesRect(Context context)
Creates the display mask according to config_mainBuiltInDisplayMaskRect.
Parameters
Context context
A context for the current activity.
Returns
DisplayMask
The new display mask.
FromResourcesRectApproximation
public static DisplayMask FromResourcesRectApproximation(Context context)
Creates the display mask according to config_mainBuiltInDisplayMaskRectApproximation, which is the closest rectangle-base approximation of the mask.
Parameters
Context context
A context for the current activity.
Returns
DisplayMask
The new display mask.
GetBoundingRects
public List<Rect> GetBoundingRects()
Returns a list of Rects, each of which is the bounding rectangle for a non-functional area on the display.
Returns
List<Rect>
A list of bounding Rects, one for each display mask area.
GetBoundingRectsForRotation
public List<Rect> GetBoundingRectsForRotation(SurfaceOrientation rotation)
Returns a list of Rects with respect to the rotation, each of which is the bounding rectangle for a non-functional area on the display.
Parameters
SurfaceOrientation rotation
The rotation mask should rotate. Possible values are SurfaceOrientation.Rotation0, SurfaceOrientation.Rotation90, SurfaceOrientation.Rotation180, SurfaceOrientation.Rotation270.
Returns
List<Rect>
A list of bounding Rects, one for each display mask area.
GetBounds
public Region GetBounds()
Returns the bounding region of the mask.
There may be more than one mask, in which case the returned Region will be non-contiguous and its bounding rect will be meaningless without intersecting it first.
Returns
Region
The bounding region of the mask. Coordinates are relative to the top-left corner of the content view and in pixel units.