{"id":481,"date":"2020-07-02T12:05:38","date_gmt":"2020-07-02T19:05:38","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=481"},"modified":"2020-09-14T18:32:22","modified_gmt":"2020-09-15T01:32:22","slug":"hinge-angle-on-surface-duo","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/hinge-angle-on-surface-duo\/","title":{"rendered":"Hinge Angle on Microsoft Surface Duo"},"content":{"rendered":"<p>\n  Hello Surface Duo developers!\n<\/p>\n<p>\n  In our <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/surface-duo-testing-tips-tricks\/?WT.c_id=blog-surfaceduoblog-joyl1216\">previous blog post<\/a>, we mentioned how to adjust the hinge angle in the Surface Duo emulator. Today we are going to present some ideas about how to take advantage of this unique behavior of the Surface Duo device.\n<\/p>\n<p>\n  As we discussed in <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/bring-to-duo\/?WT.c_id=docs-surfaceduoblog-joyl1216\">How to Bring Your Android Apps to Surface Duo<\/a>, your Android apps will work on Surface Duo just as it does on any Android device. But how can your app benefit from the dual-screen and the special hinge posture? To give you a visible picture, we created a <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-samples-kotlin\/tree\/master\/HingeAngle\">Hinge Angle Sample<\/a> in Kotlin, which contains a draw board supporting Microsoft Surface Pen with some cool features only available in the Surface Duo device. \n<\/p>\n<h2>Project Setup<\/h2>\n<\/p>\n<p>\n  If you follow our blogs or read our documentation, we walk you through the steps of how to use the Surface Duo SDK to optimize your app for dual-screen devices. Since we are building a sample from the scratch, let\u2019s start from the beginning and follow the steps below to get started:\n<\/p>\n<ol>\n<li><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/get-duo-sdk\/?WT.c_id=docs-surfaceduoblog-joyl1216\">Download the Surface Duo SDK<\/a>\n<\/li>\n<li><a href=\"https:\/\/www.microsoft.com\/download\/details.aspx?id=100847\">Install the latest emulator<\/a>\n<\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/dualscreen-layout\/?WT.c_id=docs-surfaceduoblog-joyl1216\">Set up DualScreen-Layout<\/a>\n<\/li>\n<\/ol>\n<p>\n  Once you have completed the steps above, you will be able to view your app in dual-screen mode in Design Preview of Android Studio:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1101\" height=\"688\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-18.png\" class=\"wp-image-502\" alt=\"Android Studio design preview with color palette\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-18.png 1101w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-18-300x187.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-18-1024x640.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-18-768x480.png 768w\" sizes=\"(max-width: 1101px) 100vw, 1101px\" \/>\n<\/p>\n<p>\n  Figure 1: Dual-landscape mode in Design Preview in Android Studio\n<\/p>\n<p>\n  Now let\u2019s see how we can leverage the dual-screen.\n<\/p>\n<h2>Mirror Drawing<\/h2>\n<\/p>\n<p>\n  There are two types of draw mirroring included in the sample; mirror drawing when spanned, and live draw mirroring.\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"480\" height=\"270\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/animated-gif-6.gif\" class=\"wp-image-503\" alt=\"Animated painting with reflection over the hinge\" \/>\n<\/p>\n<p>\n  Figure 2: Mirroring the drawing when spanned\n<\/p>\n<p>\n  In this example, the app starts from the single screen and features a color picker and a clear button as the basic tools to use while drawing. You can do some random drawing on this screen to test it out. When you span the single screen to dual-screen mode, your drawing will be mirrored on the second screen. \n<\/p>\n<p>\n  The basic idea is to create two <a href=\"https:\/\/developer.android.com\/guide\/components\/fragments\">fragments<\/a> to manage the mirror function. While spanning, the second fragment is created and goes through the same life cycle when the device is rotated. Since the single screen fragment will be re-created as a fragment on the dual-screen, the <a href=\"https:\/\/developer.android.com\/reference\/androidx\/lifecycle\/ViewModel\">ViewModel<\/a> is used to retain the previous drawing and copy the drawing to the second screen. The drawing is captured with <a href=\"https:\/\/developer.android.com\/reference\/android\/graphics\/Bitmap\">Bitmap<\/a> which makes it easy to flip with <a href=\"https:\/\/developer.android.com\/reference\/android\/graphics\/Matrix\">Matrix<\/a>. \n<\/p>\n<p>\n  <img decoding=\"async\" width=\"480\" height=\"270\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/animated-gif-7.gif\" class=\"wp-image-504\" alt=\"Animated painting with reflection over the hinge\" \/>\n<\/p>\n<p>\n  Figure 3: Live draw mirroring in HingeAngle sample\n<\/p>\n<p>\n  For the live draw mirroring while in dual-screen mode, when you are drawing in the main screen, the second screen will show the reflected image.\n<\/p>\n<p>\n  The trick here is the <a href=\"https:\/\/developer.android.com\/reference\/android\/view\/ViewTreeObserver\">ViewTreeObserver<\/a> setting which observes the <a href=\"https:\/\/developer.android.com\/reference\/android\/view\/View#onDraw(android.graphics.Canvas)\">onDraw<\/a> function in the \u201cView\u201d and with <a href=\"https:\/\/developer.android.com\/reference\/androidx\/lifecycle\/LiveData\">LiveData<\/a> settings, the second screen can respond accordingly.\n<\/p>\n<h2>Hinge Angle Detect<\/h2>\n<p>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/07\/animated-gif-9.gif\" alt=\"Animation of stroke width changing\" width=\"480\" height=\"270\" class=\"alignnone size-full wp-image-515\" \/>\n<\/p>\n<p>\n  Figure 4: Drawing render when folding\/unfolding\n<\/p>\n<p>\n  You can see in the sample that there is a label showing the number which is used to represent the current hinge angle of the device. As discussed in the <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/hinge-sensor?WT.c_id=docs-surfaceduoblog-joyl1216\">Hinge Angle Sensor API documentation<\/a>, we can <a href=\"https:\/\/developer.android.com\/guide\/topics\/sensors\/sensors_overview#sensors-monitor\">detect the hinge angle<\/a> with the <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/SensorEventListener\">SensorEventListener<\/a>. Here is some sample code in Kotlin for reference:\n<\/p>\n<pre>private val hingeAngleSensorListener = object : SensorEventListener {\r\n    override fun onSensorChanged(event: SensorEvent) {\r\n        if (event.sensor == hingeAngleSensor) {\r\n            val angle = event.values[0].toInt()\r\n            val viewModel = ViewModelProvider(requireActivity()).get(ViewModel::class.java)\r\n            viewModel.setHingeAngleLiveData(angle)\r\n        }\r\n    }\r\n\r\n    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {\r\n    }\r\n}\r\n\r\nprivate fun setupSensors() {\r\n    sensorManager = requireActivity().getSystemService(Service.SENSOR_SERVICE) as SensorManager?\r\n    sensorManager?.let {\r\n        val sensorList: List<Sensor> = it.getSensorList(Sensor.TYPE_ALL)\r\n        for (sensor in sensorList) {\r\n            if (sensor.name.contains(HINGE_ANGLE_SENSOR_NAME)) {\r\n                hingeAngleSensor = sensor\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>\n  You can see <strong>ViewModel<\/strong> and <strong>LiveData<\/strong> are used here again to save the hinge angle returning from <strong>SensorEventListener<\/strong>. This enables the app to observe these values and implement features accordingly. In the sample, we render the drawing based on the hinge angle to achieve the gradient effect.\n<\/p>\n<p>\n  To test it in the emulator, go to the Extended controls window, select\u00a0<strong>Virtual Sensors<\/strong> &gt; <strong>Additional sensors<\/strong>\u00a0and slide the\u00a0<strong>Pressure\u00a0control<\/strong> between 0 and 360 as mentioned in our <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/surface-duo-testing-tips-tricks\/?WT.c_id=blog-surfaceduoblog-joyl1216\">Surface Duo testing tips and tricks<\/a> blog post. When adjusting the hinge angle in the emulator, or when you fold or unfold the device, you will see the drawing changing gradually. We are still working on implementing additional methods to enable more visible control, so stay tuned to future blog posts for more tips!\n<\/p>\n<h2>Adjusting pen stroke width using pressure setting<\/h2>\n<\/p>\n<p>\n  In previous blogs, we also talked about <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/pen-events-on-the-surface-duo\/?WT.c_id=blog-surfaceduoblog-joyl1216\">Pen Events<\/a> with Microsoft Surface Pen. In our sample below, we have also used the pen pressure setting (which usually falls between 0 to 1) to modify the stroke width of <a href=\"https:\/\/developer.android.com\/reference\/android\/graphics\/Paint\">Paint class<\/a>  used in the drawing.\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1334\" height=\"863\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/a-screenshot-of-a-cell-phone-description-automati-4.png\" class=\"wp-image-506\" alt=\"Screenshot of reflected painting on both screens\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/a-screenshot-of-a-cell-phone-description-automati-4.png 1334w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/a-screenshot-of-a-cell-phone-description-automati-4-300x194.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/a-screenshot-of-a-cell-phone-description-automati-4-1024x662.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/a-screenshot-of-a-cell-phone-description-automati-4-768x497.png 768w\" sizes=\"(max-width: 1334px) 100vw, 1334px\" \/>\n<\/p>\n<p>\n  Figure 5: Drawing render in HingeAngle sample\n<\/p>\n<h2>Feedback<\/h2>\n<\/p>\n<p>\n  I hope this sample provides you with some additional ways to enhance the user experience in your app to take advantage of the distinctive features of the Microsoft Surface Duo device. \n<\/p>\n<p>\n  All of our sample code is open sourced and we welcome your contributions directly in our <a href=\"https:\/\/github.com\/microsoft\/surface-duo-sdk-samples\">GitHub<\/a> repo to evolve the sample into an awesome Rorschach Painter! We\u2019d love to hear from you so please leave us feedback using our\u00a0<a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a>, or message me on <a href=\"https:\/\/twitter.com\/joyl1216\">Twitter<\/a> or <a href=\"https:\/\/github.com\/joyl1216\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Surface Duo developers! In our previous blog post, we mentioned how to adjust the hinge angle in the Surface Duo emulator. Today we are going to present some ideas about how to take advantage of this unique behavior of the Surface Duo device. As we discussed in How to Bring Your Android Apps to [&hellip;]<\/p>\n","protected":false},"author":30456,"featured_media":513,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[607,46,45],"class_list":["post-481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-hinge","tag-surface-duo","tag-surface-duo-sdk"],"acf":[],"blog_post_summary":"<p>Hello Surface Duo developers! In our previous blog post, we mentioned how to adjust the hinge angle in the Surface Duo emulator. Today we are going to present some ideas about how to take advantage of this unique behavior of the Surface Duo device. As we discussed in How to Bring Your Android Apps to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/481","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/30456"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=481"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/481\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/513"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}