Last December I wrote a blog post called "The Seven GUIs of Christmas" as part of the Third Annual C# Advent series. This post showed the use of the Uno Platform to write cross-platform apps in UWP. One of the major drivers behind this blog post a desire to write apps for Microsoft's recently announced Surface Neo and Surface Duo devices which run Windows 10X and Android respectively. Well, a couple of days ago, Microsoft finally released a preview SDK for the Surface Duo which included an Android Emulator with a preview Surface Duo image. Today I finally got a chance to see whether the Uno Platform really could deliver on these new form-factors.
Installing the Emulator
If, like me, you don't have Android Studio installed and/or you want to install the Surface Duo SDK in a non-standard location (my super-speedy Intel Optane 900P C:\ drive is getting a little crowded!), you're going to face issues running the emulator. This is mostly due to the
run.bat file used to launch the emulator not looking in the correct location for the Android SDK and not supporting installation of the Surface Duo SDK in a path that contains spaces.
If you're encountering issues launching the emulator, navigate to the
artifacts directory within the Surface Duo SDK installation directory and edit the
run.bat file to the following:
@echo off rem ##### ENSURE THE SDK LOCATION BELOW IS CORRECT: ####### set ANDROID_SDK_LOCATION=C:\Program Files (x86)\Android\android-sdk rem ############ DO NOT Modify below this line ############ set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=.\ echo %DIRNAME% rem Check if emulator is installed set EMULATOR=%ANDROID_SDK_LOCATION%\emulator\emulator.exe echo "%EMULATOR%" if exist %EMULATOR% ( set ANDROID_PRODUCT_OUT=%DIRNAME% "%EMULATOR%" -verbose -accel auto %* -sysdir "%DIRNAME%\bin" -kernel "%DIRNAME%\bin\kernel-ranchu" -datadir "%DIRNAME%\bin\data" -initdata "%DIRNAME%\bin\userdata.img" -vendor "%DIRNAME%\bin\vendor-qemu.img" -system "%DIRNAME%\bin\system-qemu.img" -initdata "%DIRNAME%\bin\userdata.img" -data "%DIRNAME%\bin\userdata.img" ) else ( echo "Can't find emulator executable, make sure its installed" )
TBH, the changes are mostly just encapsulating paths within quotes but hopefully this'll save you a little time.
Hopefully now, when you launch the emulator, you'll be greeted by this:
Hmm... dual screens!
Microsoft have done a great job of helping developers get started on this platform by supplying some great code-snippets and samples in both Java and C# (using the Xamarin platform). Furthermore, the emulator "just works" with the Visual Studio IDE such that, once running, it appears as a standard deployment target allowing you to quickly get apps running within the Surface Duo image.
My first priority with Uno was to make sure I could correctly interpret when the app was running on a single screen or across both screens. To do this, I took a look at the Xamarin samples and quickly saw that they used a
ScreenHelper class to collate information on the current state of the app. This class is provided as part of the (very new - just two days old at time of writing!) Xamarin.DuoSdk nuget package. Fortunately, when running on Android (or iOS), Uno runs on top of Xamarin meaning I could just add a reference to this package from the
Droid head project of my Uno solution and start using this class right away.
The main functions of the
ScreenHelper class were abstracted behind an
IDeviceHelper interface so that each head project could provide a platform specific implementation and a small shim written around the
ScreenHelper class to satisfy this interface. Finally, to provide responsiveness to changes, I again used my MVx.Observable nuget package to dynamically call
IDeviceHelper members and update properties on a view model whenever the application changed modes.
In very short order, I had this working:
Just to highlight: this is completely standard UWP / C# code, running unchanged on a dual-screen Android device.
A few comments / caveats:
- The loading time of the Uno app in the emulator was due to the app being run, as debug, directly from the Visual Studio IDE and is not indicative of Uno Platform app start times.
- The app disappearing when switching between screens or between single and dual screen modes is not due to the Uno Platform; this happen with apps that come as part of the Duo image.
- Occasionally, when switching between single and dual screen modes, the app will just disappear. Again, this is nothing to do with the Uno Platform and happens with apps that come as part of the Duo image.
While the Surface Duo Android Emulator image is undoubtedly rough around the edges (it is, after all, a preview) it manages to provide a tantalising taste of what using dual-screen devices could be like. Indeed, just running the Contacts and Calendar apps side-by-side boggles the mind with possible interactions between the two. Furthermore Microsoft have, in relatively short order, delivered a preview SDK from which it is possible to start developing new dual-screen apps or enhance existing apps to take advantage of a second screen. Exciting times!
Per my experience while writing "The Seven GUIs of Christmas" post, the Uno Platform has continued to preform admirably and shows great promise for writing apps that will run natively across platforms and on dual screens. The only issue I had with Uno while writing the app above was the use of a "Shared Project" to share the Xaml/ViewModel between the various head projects. This approach (which I recommended against in my previous post) resulted in Visual Studio stubbornly refusing to show the Xaml editor and countless errors being shown in the error window despite everything compiling and running fine.
All code for this post can be found in my UnoDuoHey repository on Github.
I am currently eager to find potential new clients interested in using the Uno Platform to deliver cross-platform apps and those looking to capitalise on the amazing potential of dual-screen devices in particular. If this sounds like you or your company, please feel free to drop me a line to discuss your project/ideas using any of the links below or from my about page.